parse-server 4.10.2 → 5.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +450 -153
- package/lib/AccountLockout.js +23 -2
- package/lib/Adapters/AdapterLoader.js +1 -1
- package/lib/Adapters/Analytics/AnalyticsAdapter.js +1 -1
- package/lib/Adapters/Auth/AuthAdapter.js +1 -1
- package/lib/Adapters/Auth/OAuth1Client.js +1 -1
- package/lib/Adapters/Auth/facebook.js +110 -10
- package/lib/Adapters/Auth/gcenter.js +1 -1
- package/lib/Adapters/Auth/gpgames.js +1 -1
- package/lib/Adapters/Auth/instagram.js +4 -2
- package/lib/Adapters/Auth/keycloak.js +1 -1
- package/lib/Adapters/Auth/ldap.js +3 -1
- package/lib/Adapters/Auth/oauth2.js +1 -1
- package/lib/Adapters/Auth/phantauth.js +1 -1
- package/lib/Adapters/Cache/CacheAdapter.js +1 -1
- package/lib/Adapters/Cache/RedisCacheAdapter.js +143 -0
- package/lib/Adapters/Cache/SchemaCache.js +31 -0
- package/lib/Adapters/Email/MailAdapter.js +1 -1
- package/lib/Adapters/Files/FilesAdapter.js +1 -1
- package/lib/Adapters/Files/GridFSBucketAdapter.js +1 -1
- package/lib/Adapters/Files/GridStoreAdapter.js +1 -1
- package/lib/Adapters/Logger/LoggerAdapter.js +1 -1
- package/lib/Adapters/Logger/WinstonLogger.js +4 -4
- package/lib/Adapters/PubSub/EventEmitterPubSub.js +5 -1
- package/lib/Adapters/PubSub/PubSubAdapter.js +1 -1
- package/lib/Adapters/Push/PushAdapter.js +1 -1
- package/lib/Adapters/Storage/Mongo/MongoCollection.js +1 -1
- package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +1 -1
- package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +51 -11
- package/lib/Adapters/Storage/Mongo/MongoTransform.js +9 -6
- package/lib/Adapters/Storage/Postgres/PostgresClient.js +11 -1
- package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +91 -57
- package/lib/Adapters/WebSocketServer/WSAdapter.js +1 -1
- package/lib/Adapters/WebSocketServer/WSSAdapter.js +1 -1
- package/lib/Auth.js +2 -39
- package/lib/Config.js +149 -8
- package/lib/Controllers/AdaptableController.js +1 -9
- package/lib/Controllers/CacheController.js +1 -1
- package/lib/Controllers/DatabaseController.js +148 -44
- package/lib/Controllers/FilesController.js +1 -1
- package/lib/Controllers/HooksController.js +2 -2
- package/lib/Controllers/LiveQueryController.js +16 -3
- package/lib/Controllers/LoggerController.js +1 -1
- package/lib/Controllers/ParseGraphQLController.js +2 -2
- package/lib/Controllers/PushController.js +1 -1
- package/lib/Controllers/SchemaController.js +101 -88
- package/lib/Controllers/UserController.js +16 -5
- package/lib/Controllers/index.js +10 -11
- package/lib/Deprecator/Deprecations.js +28 -0
- package/lib/Deprecator/Deprecator.js +135 -0
- package/lib/GraphQL/ParseGraphQLSchema.js +71 -39
- package/lib/GraphQL/ParseGraphQLServer.js +3 -3
- package/lib/GraphQL/loaders/defaultGraphQLMutations.js +2 -2
- package/lib/GraphQL/loaders/defaultGraphQLQueries.js +2 -2
- package/lib/GraphQL/loaders/defaultGraphQLTypes.js +4 -7
- package/lib/GraphQL/loaders/defaultRelaySchema.js +3 -3
- package/lib/GraphQL/loaders/filesMutations.js +2 -2
- package/lib/GraphQL/loaders/functionsMutations.js +9 -5
- package/lib/GraphQL/loaders/parseClassMutations.js +21 -9
- package/lib/GraphQL/loaders/parseClassQueries.js +9 -6
- package/lib/GraphQL/loaders/parseClassTypes.js +5 -5
- package/lib/GraphQL/loaders/schemaDirectives.js +1 -1
- package/lib/GraphQL/loaders/schemaMutations.js +8 -6
- package/lib/GraphQL/loaders/schemaQueries.js +6 -4
- package/lib/GraphQL/loaders/usersMutations.js +65 -7
- package/lib/GraphQL/transformers/constraintType.js +2 -2
- package/lib/GraphQL/transformers/inputType.js +2 -2
- package/lib/GraphQL/transformers/mutation.js +45 -10
- package/lib/GraphQL/transformers/outputType.js +2 -2
- package/lib/GraphQL/transformers/query.js +2 -2
- package/lib/GraphQL/transformers/schemaFields.js +1 -1
- package/lib/KeyPromiseQueue.js +59 -0
- package/lib/LiveQuery/Client.js +1 -1
- package/lib/LiveQuery/Id.js +1 -1
- package/lib/LiveQuery/ParseLiveQueryServer.js +158 -38
- package/lib/LiveQuery/ParseWebSocketServer.js +2 -2
- package/lib/LiveQuery/QueryTools.js +50 -1
- package/lib/LiveQuery/equalObjects.js +1 -1
- package/lib/Options/Definitions.js +220 -33
- package/lib/Options/docs.js +79 -21
- package/lib/Options/index.js +3 -1
- package/lib/Page.js +53 -0
- package/lib/ParseServer.js +37 -16
- package/lib/ParseServerRESTController.js +55 -45
- package/lib/PromiseRouter.js +7 -20
- package/lib/Push/PushQueue.js +1 -1
- package/lib/Push/PushWorker.js +2 -2
- package/lib/Push/utils.js +1 -1
- package/lib/RestQuery.js +45 -9
- package/lib/RestWrite.js +60 -10
- package/lib/Routers/AggregateRouter.js +23 -18
- package/lib/Routers/AudiencesRouter.js +2 -2
- package/lib/Routers/ClassesRouter.js +11 -11
- package/lib/Routers/CloudCodeRouter.js +1 -1
- package/lib/Routers/FeaturesRouter.js +2 -2
- package/lib/Routers/FilesRouter.js +34 -7
- package/lib/Routers/FunctionsRouter.js +2 -2
- package/lib/Routers/GlobalConfigRouter.js +2 -2
- package/lib/Routers/GraphQLRouter.js +3 -3
- package/lib/Routers/HooksRouter.js +2 -2
- package/lib/Routers/LogsRouter.js +2 -2
- package/lib/Routers/PagesRouter.js +722 -0
- package/lib/Routers/PurgeRouter.js +2 -2
- package/lib/Routers/PushRouter.js +3 -3
- package/lib/Routers/SchemasRouter.js +2 -2
- package/lib/Routers/SecurityRouter.js +47 -0
- package/lib/Routers/SessionsRouter.js +4 -2
- package/lib/Routers/UsersRouter.js +88 -17
- package/lib/Security/Check.js +118 -0
- package/lib/Security/CheckGroup.js +54 -0
- package/lib/Security/CheckGroups/CheckGroupDatabase.js +57 -0
- package/lib/Security/CheckGroups/CheckGroupServerConfig.js +82 -0
- package/lib/Security/CheckGroups/CheckGroups.js +24 -0
- package/lib/Security/CheckRunner.js +236 -0
- package/lib/StatusHandler.js +27 -36
- package/lib/TestUtils.js +1 -1
- package/lib/Utils.js +226 -0
- package/lib/batch.js +55 -44
- package/lib/cli/utils/commander.js +8 -3
- package/lib/cloud-code/HTTPResponse.js +1 -1
- package/lib/cloud-code/Parse.Cloud.js +155 -19
- package/lib/cloud-code/httpRequest.js +1 -1
- package/lib/index.js +6 -12
- package/lib/middlewares.js +39 -4
- package/lib/rest.js +4 -4
- package/lib/triggers.js +134 -121
- package/lib/vendor/mongodbUrl.js +8 -10
- package/package.json +54 -29
- package/CHANGELOG.md +0 -1769
- package/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js +0 -59
- package/lib/Adapters/Cache/RedisCacheAdapter/index.js +0 -130
- package/lib/Controllers/SchemaCache.js +0 -75
package/README.md
CHANGED
|
@@ -1,77 +1,96 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<h2 align="center">Our Sponsors</h2>
|
|
28
|
-
<p align="center">
|
|
29
|
-
<p align="center">Our backers and sponsors help to ensure the quality and timely development of the Parse Platform.</p>
|
|
30
|
-
<details align="center">
|
|
31
|
-
<summary align="center"><b>🥉 Bronze Sponsors</b></summary>
|
|
32
|
-
<a href="https://opencollective.com/parse-server/sponsor/0/website" target="_blank"><img src="https://opencollective.com/parse-server/sponsor/0/avatar.svg"></a>
|
|
33
|
-
</details>
|
|
34
|
-
|
|
35
|
-
</p>
|
|
36
|
-
<p align="center">
|
|
37
|
-
<a href="#backers"><img alt="Backers on Open Collective" src="https://opencollective.com/parse-server/tiers/backers/badge.svg" /></a>
|
|
38
|
-
<a href="#sponsors"><img alt="Sponsors on Open Collective" src="https://opencollective.com/parse-server/tiers/sponsors/badge.svg" /></a>
|
|
39
|
-
</p>
|
|
40
|
-
<br>
|
|
41
|
-
|
|
42
|
-
Parse Server works with the Express web application framework. It can be added to existing web applications, or run by itself.
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
[](https://github.com/parse-community/parse-server/actions?query=workflow%3Aci+branch%3Amaster)
|
|
6
|
+
[](https://snyk.io/test/github/parse-community/parse-server)
|
|
7
|
+
[](https://codecov.io/github/parse-community/parse-server?branch=master)
|
|
8
|
+
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+
[](https://www.mongodb.com)
|
|
11
|
+
[](https://www.postgresql.org)
|
|
12
|
+
[](https://github.com/parse-community/parse-dashboard/releases)
|
|
13
|
+
|
|
14
|
+
[](https://www.npmjs.com/package/parse-server)
|
|
15
|
+
[](https://www.npmjs.com/package/parse-server)
|
|
16
|
+
<!-- [](https://www.npmjs.com/package/parse-server) -->
|
|
17
|
+
|
|
18
|
+
[][open-collective-link]
|
|
19
|
+
[][open-collective-link]
|
|
20
|
+
[![License][license-svg]][license-link]
|
|
21
|
+
[](https://community.parseplatform.org/c/parse-server)
|
|
22
|
+
[](https://twitter.com/intent/follow?screen_name=ParsePlatform)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
Parse Server is an open source backend that can be deployed to any infrastructure that can run Node.js. Parse Server works with the Express web application framework. It can be added to existing web applications, or run by itself.
|
|
43
27
|
|
|
44
28
|
The full documentation for Parse Server is available in the [wiki](https://github.com/parse-community/parse-server/wiki). The [Parse Server guide](http://docs.parseplatform.org/parse-server/guide/) is a good place to get started. An [API reference](http://parseplatform.org/parse-server/api/) and [Cloud Code guide](https://docs.parseplatform.org/cloudcode/guide/) are also available. If you're interested in developing for Parse Server, the [Development guide](http://docs.parseplatform.org/parse-server/guide/#development-guide) will help you get set up.
|
|
45
29
|
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
A big *thank you* to all our backers and sponsors who support the development of Parse Platform!
|
|
33
|
+
|
|
34
|
+
### 💎 Diamond Sponsors
|
|
35
|
+
|
|
36
|
+
[](https://opencollective.com/parse-server/sponsor/0/website)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
46
40
|
- [Getting Started](#getting-started)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- [
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
- [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
- [
|
|
41
|
+
- [Running Parse Server](#running-parse-server)
|
|
42
|
+
- [Compatibility](#compatibility)
|
|
43
|
+
- [Node.js](#nodejs)
|
|
44
|
+
- [MongoDB](#mongodb)
|
|
45
|
+
- [PostgreSQL](#postgresql)
|
|
46
|
+
- [Locally](#locally)
|
|
47
|
+
- [Docker Container](#docker-container)
|
|
48
|
+
- [Saving an Object](#saving-an-object)
|
|
49
|
+
- [Connect an SDK](#connect-an-sdk)
|
|
50
|
+
- [Running Parse Server elsewhere](#running-parse-server-elsewhere)
|
|
51
|
+
- [Sample Application](#sample-application)
|
|
52
|
+
- [Parse Server + Express](#parse-server--express)
|
|
53
|
+
- [Configuration](#configuration)
|
|
54
|
+
- [Basic Options](#basic-options)
|
|
55
|
+
- [Client Key Options](#client-key-options)
|
|
56
|
+
- [Email Verification and Password Reset](#email-verification-and-password-reset)
|
|
57
|
+
- [Password and Account Policy](#password-and-account-policy)
|
|
58
|
+
- [Custom Routes](#custom-routes)
|
|
59
|
+
- [Example](#example)
|
|
60
|
+
- [Reserved Paths](#reserved-paths)
|
|
61
|
+
- [Parameters](#parameters)
|
|
62
|
+
- [Custom Pages](#custom-pages)
|
|
63
|
+
- [Using Environment Variables](#using-environment-variables)
|
|
64
|
+
- [Available Adapters](#available-adapters)
|
|
65
|
+
- [Configuring File Adapters](#configuring-file-adapters)
|
|
66
|
+
- [Idempotency Enforcement](#idempotency-enforcement)
|
|
67
|
+
- [Localization](#localization)
|
|
68
|
+
- [Pages](#pages)
|
|
69
|
+
- [Localization with Directory Structure](#localization-with-directory-structure)
|
|
70
|
+
- [Localization with JSON Resource](#localization-with-json-resource)
|
|
71
|
+
- [Dynamic placeholders](#dynamic-placeholders)
|
|
72
|
+
- [Reserved Keys](#reserved-keys)
|
|
73
|
+
- [Parameters](#parameters-1)
|
|
74
|
+
- [Logging](#logging)
|
|
75
|
+
- [Deprecations](#deprecations)
|
|
76
|
+
- [Live Query](#live-query)
|
|
65
77
|
- [GraphQL](#graphql)
|
|
78
|
+
- [Running](#running)
|
|
79
|
+
- [Using the CLI](#using-the-cli)
|
|
80
|
+
- [Using Docker](#using-docker)
|
|
81
|
+
- [Using Express.js](#using-expressjs)
|
|
82
|
+
- [Checking the API health](#checking-the-api-health)
|
|
83
|
+
- [Creating your first class](#creating-your-first-class)
|
|
84
|
+
- [Using automatically generated operations](#using-automatically-generated-operations)
|
|
85
|
+
- [Customizing your GraphQL Schema](#customizing-your-graphql-schema)
|
|
86
|
+
- [Learning more](#learning-more)
|
|
66
87
|
- [Upgrading to 3.0.0](#upgrading-to-300)
|
|
67
|
-
- [
|
|
68
|
-
- [Ride the Bleeding Edge](#want-to-ride-the-bleeding-edge)
|
|
88
|
+
- [Want to ride the bleeding edge?](#want-to-ride-the-bleeding-edge)
|
|
69
89
|
- [Contributing](#contributing)
|
|
70
90
|
- [Contributors](#contributors)
|
|
71
91
|
- [Sponsors](#sponsors)
|
|
72
92
|
- [Backers](#backers)
|
|
73
93
|
|
|
74
|
-
|
|
75
94
|
# Getting Started
|
|
76
95
|
|
|
77
96
|
The fastest and easiest way to get started is to run MongoDB and Parse Server locally.
|
|
@@ -84,6 +103,36 @@ Before you start make sure you have installed:
|
|
|
84
103
|
- [MongoDB](https://www.mongodb.com/) or [PostgreSQL](https://www.postgresql.org/)(with [PostGIS](https://postgis.net) 2.2.0 or higher)
|
|
85
104
|
- Optionally [Docker](https://www.docker.com/)
|
|
86
105
|
|
|
106
|
+
### Compatibility
|
|
107
|
+
|
|
108
|
+
#### Node.js
|
|
109
|
+
Parse Server is continuously tested with the most recent releases of Node.js to ensure compatibility. We follow the [Node.js Long Term Support plan](https://github.com/nodejs/Release) and only test against versions that are officially supported and have not reached their end-of-life date.
|
|
110
|
+
|
|
111
|
+
| Version | Latest Version | End-of-Life Date | Compatibility |
|
|
112
|
+
|------------|----------------|------------------|--------------------|
|
|
113
|
+
| Node.js 12 | 12.22.7 | April 2022 | ✅ Fully compatible |
|
|
114
|
+
| Node.js 14 | 14.18.1 | April 2023 | ✅ Fully compatible |
|
|
115
|
+
| Node.js 15 | 15.14.0 | June 2021 | ✅ Fully compatible |
|
|
116
|
+
|
|
117
|
+
#### MongoDB
|
|
118
|
+
Parse Server is continuously tested with the most recent releases of MongoDB to ensure compatibility. We follow the [MongoDB support schedule](https://www.mongodb.com/support-policy) and only test against versions that are officially supported and have not reached their end-of-life date.
|
|
119
|
+
|
|
120
|
+
| Version | Latest Version | End-of-Life Date | Compatibility |
|
|
121
|
+
|-------------|----------------|------------------|--------------------|
|
|
122
|
+
| MongoDB 4.0 | 4.0.27 | April 2022 | ✅ Fully compatible |
|
|
123
|
+
| MongoDB 4.2 | 4.2.17 | TBD | ✅ Fully compatible |
|
|
124
|
+
| MongoDB 4.4 | 4.4.10 | TBD | ✅ Fully compatible |
|
|
125
|
+
| MongoDB 5.0 | 5.0.3 | January 2024 | ✅ Fully compatible |
|
|
126
|
+
|
|
127
|
+
#### PostgreSQL
|
|
128
|
+
Parse Server is continuously tested with the most recent releases of PostgreSQL and PostGIS to ensure compatibility, using [PostGIS docker images](https://registry.hub.docker.com/r/postgis/postgis/tags?page=1&ordering=last_updated). We follow the [PostgreSQL support schedule](https://www.postgresql.org/support/versioning) and [PostGIS support schedule](https://www.postgis.net/eol_policy/) and only test against versions that are officially supported and have not reached their end-of-life date. Due to the extensive PostgreSQL support duration of 5 years, Parse Server drops support if a version is older than 3.5 years and a newer version has been available for at least 2.5 years.
|
|
129
|
+
|
|
130
|
+
| Version | PostGIS Version | End-of-Life Date | Parse Server Support End | Compatibility |
|
|
131
|
+
|-------------|-----------------|------------------|--------------------------|--------------------|
|
|
132
|
+
| Postgres 11 | 3.0, 3.1 | November 2023 | April 2022 | ✅ Fully compatible |
|
|
133
|
+
| Postgres 12 | 3.1 | November 2024 | April 2023 | ✅ Fully compatible |
|
|
134
|
+
| Postgres 13 | 3.1 | November 2025 | April 2024 | ✅ Fully compatible |
|
|
135
|
+
|
|
87
136
|
### Locally
|
|
88
137
|
```bash
|
|
89
138
|
$ npm install -g parse-server mongodb-runner
|
|
@@ -93,7 +142,7 @@ $ parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongo
|
|
|
93
142
|
***Note:*** *If installation with* `-g` *fails due to permission problems* (`npm ERR! code 'EACCES'`), *please refer to [this link](https://docs.npmjs.com/getting-started/fixing-npm-permissions).*
|
|
94
143
|
|
|
95
144
|
|
|
96
|
-
###
|
|
145
|
+
### Docker Container
|
|
97
146
|
|
|
98
147
|
```bash
|
|
99
148
|
$ git clone https://github.com/parse-community/parse-server
|
|
@@ -102,13 +151,13 @@ $ docker build --tag parse-server .
|
|
|
102
151
|
$ docker run --name my-mongo -d mongo
|
|
103
152
|
```
|
|
104
153
|
|
|
105
|
-
#### Running the Parse Server Image
|
|
154
|
+
#### Running the Parse Server Image <!-- omit in toc -->
|
|
106
155
|
|
|
107
156
|
```bash
|
|
108
157
|
$ docker run --name my-parse-server -v config-vol:/parse-server/config -p 1337:1337 --link my-mongo:mongo -d parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongodb://mongo/test
|
|
109
158
|
```
|
|
110
159
|
|
|
111
|
-
***Note:*** *If you want to use [Cloud Code](https://docs.parseplatform.org/cloudcode/guide/)
|
|
160
|
+
***Note:*** *If you want to use [Cloud Code](https://docs.parseplatform.org/cloudcode/guide/), add `-v cloud-code-vol:/parse-server/cloud --cloud /parse-server/cloud/main.js` to the command above. Make sure `main.js` is in the `cloud-code-vol` directory before starting Parse Server.*
|
|
112
161
|
|
|
113
162
|
You can use any arbitrary string as your application id and master key. These will be used by your clients to authenticate with the Parse Server.
|
|
114
163
|
|
|
@@ -116,7 +165,7 @@ That's it! You are now running a standalone version of Parse Server on your mach
|
|
|
116
165
|
|
|
117
166
|
**Using a remote MongoDB?** Pass the `--databaseURI DATABASE_URI` parameter when starting `parse-server`. Learn more about configuring Parse Server [here](#configuration). For a full list of available options, run `parse-server --help`.
|
|
118
167
|
|
|
119
|
-
### Saving
|
|
168
|
+
### Saving an Object
|
|
120
169
|
|
|
121
170
|
Now that you're running Parse Server, it is time to save your first object. We'll use the [REST API](http://docs.parseplatform.org/rest/guide), but you can easily do the same using any of the [Parse SDKs](http://parseplatform.org/#sdks). Run the following:
|
|
122
171
|
|
|
@@ -182,7 +231,7 @@ $ curl -X GET \
|
|
|
182
231
|
|
|
183
232
|
To learn more about using saving and querying objects on Parse Server, check out the [Parse documentation](http://docs.parseplatform.org).
|
|
184
233
|
|
|
185
|
-
### Connect
|
|
234
|
+
### Connect an SDK
|
|
186
235
|
|
|
187
236
|
Parse provides SDKs for all the major platforms. Refer to the Parse Server guide to [learn how to connect your app to Parse Server](https://docs.parseplatform.org/parse-server/guide/#using-parse-sdks-with-parse-server).
|
|
188
237
|
|
|
@@ -190,7 +239,7 @@ Parse provides SDKs for all the major platforms. Refer to the Parse Server guide
|
|
|
190
239
|
|
|
191
240
|
Once you have a better understanding of how the project works, please refer to the [Parse Server wiki](https://github.com/parse-community/parse-server/wiki) for in-depth guides to deploy Parse Server to major infrastructure providers. Read on to learn more about additional ways of running Parse Server.
|
|
192
241
|
|
|
193
|
-
###
|
|
242
|
+
### Sample Application
|
|
194
243
|
|
|
195
244
|
We have provided a basic [Node.js application](https://github.com/parse-community/parse-server-example) that uses the Parse Server module on Express and can be easily deployed to various infrastructure providers:
|
|
196
245
|
|
|
@@ -201,7 +250,7 @@ We have provided a basic [Node.js application](https://github.com/parse-communit
|
|
|
201
250
|
* [SashiDo](https://blog.sashido.io/tag/migration/)
|
|
202
251
|
* [Digital Ocean](https://www.digitalocean.com/community/tutorials/how-to-run-parse-server-on-ubuntu-14-04)
|
|
203
252
|
* [Pivotal Web Services](https://github.com/cf-platform-eng/pws-parse-server)
|
|
204
|
-
* [Back4app](
|
|
253
|
+
* [Back4app](https://www.back4app.com/docs/get-started/welcome)
|
|
205
254
|
* [Glitch](https://glitch.com/edit/#!/parse-server)
|
|
206
255
|
* [Flynn](https://flynn.io/blog/parse-apps-on-flynn)
|
|
207
256
|
|
|
@@ -233,13 +282,13 @@ app.listen(1337, function() {
|
|
|
233
282
|
|
|
234
283
|
For a full list of available options, run `parse-server --help` or take a look at [Parse Server Configurations](http://parseplatform.org/parse-server/api/master/ParseServerOptions.html).
|
|
235
284
|
|
|
236
|
-
|
|
285
|
+
# Configuration
|
|
237
286
|
|
|
238
287
|
Parse Server can be configured using the following options. You may pass these as parameters when running a standalone `parse-server`, or by loading a configuration file in JSON format using `parse-server path/to/configuration.json`. If you're using Parse Server on Express, you may also pass these to the `ParseServer` object as options.
|
|
239
288
|
|
|
240
289
|
For the full list of available options, run `parse-server --help` or take a look at [Parse Server Configurations](http://parseplatform.org/parse-server/api/master/ParseServerOptions.html).
|
|
241
290
|
|
|
242
|
-
|
|
291
|
+
## Basic Options
|
|
243
292
|
|
|
244
293
|
* `appId` **(required)** - The application id to host with this server instance. You can use any arbitrary string. For migrated apps, this should match your hosted Parse app.
|
|
245
294
|
* `masterKey` **(required)** - The master key to use for overriding ACL security. You can use any arbitrary string. Keep it secret! For migrated apps, this should match your hosted Parse app.
|
|
@@ -247,9 +296,9 @@ For the full list of available options, run `parse-server --help` or take a look
|
|
|
247
296
|
* `port` - The default port is 1337, specify this parameter to use a different port.
|
|
248
297
|
* `serverURL` - URL to your Parse Server (don't forget to specify http:// or https://). This URL will be used when making requests to Parse Server from Cloud Code.
|
|
249
298
|
* `cloud` - The absolute path to your cloud code `main.js` file.
|
|
250
|
-
* `push` - Configuration options for APNS and GCM push. See the [Push Notifications quick start](
|
|
299
|
+
* `push` - Configuration options for APNS and GCM push. See the [Push Notifications quick start](https://docs.parseplatform.org/parse-server/guide/#push-notifications-quick-start).
|
|
251
300
|
|
|
252
|
-
|
|
301
|
+
## Client Key Options
|
|
253
302
|
|
|
254
303
|
The client keys used with Parse are no longer necessary with Parse Server. If you wish to still require them, perhaps to be able to refuse access to older clients, you can set the keys at initialization time. Setting any of these keys will require all requests to provide one of the configured keys.
|
|
255
304
|
|
|
@@ -258,76 +307,34 @@ The client keys used with Parse are no longer necessary with Parse Server. If yo
|
|
|
258
307
|
* `restAPIKey`
|
|
259
308
|
* `dotNetKey`
|
|
260
309
|
|
|
261
|
-
|
|
310
|
+
## Email Verification and Password Reset
|
|
262
311
|
|
|
263
|
-
Verifying user email addresses and enabling password reset via email requires an email adapter.
|
|
312
|
+
Verifying user email addresses and enabling password reset via email requires an email adapter. There are many email adapters provided and maintained by the community. The following is an example configuration with an example email adapter. See the [Parse Server Options](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html) for more details and a full list of available options.
|
|
264
313
|
|
|
265
314
|
```js
|
|
266
|
-
|
|
315
|
+
const server = ParseServer({
|
|
267
316
|
...otherOptions,
|
|
317
|
+
|
|
268
318
|
// Enable email verification
|
|
269
319
|
verifyUserEmails: true,
|
|
270
320
|
|
|
271
|
-
//
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
//
|
|
275
|
-
// email verify token expires after `emailVerifyTokenValidityDuration`
|
|
276
|
-
//
|
|
277
|
-
// `emailVerifyTokenValidityDuration` defaults to `undefined`
|
|
278
|
-
//
|
|
279
|
-
// email verify token below expires in 2 hours (= 2 * 60 * 60 == 7200 seconds)
|
|
280
|
-
emailVerifyTokenValidityDuration: 2 * 60 * 60, // in seconds (2 hours = 7200 seconds)
|
|
281
|
-
|
|
282
|
-
// set preventLoginWithUnverifiedEmail to false to allow user to login without verifying their email
|
|
283
|
-
// set preventLoginWithUnverifiedEmail to true to prevent user from login if their email is not verified
|
|
284
|
-
preventLoginWithUnverifiedEmail: false, // defaults to false
|
|
285
|
-
|
|
286
|
-
// The public URL of your app.
|
|
287
|
-
// This will appear in the link that is used to verify email addresses and reset passwords.
|
|
288
|
-
// Set the mount path as it is in serverURL
|
|
289
|
-
publicServerURL: 'https://example.com/parse',
|
|
290
|
-
// Your apps name. This will appear in the subject and body of the emails that are sent.
|
|
291
|
-
appName: 'Parse App',
|
|
292
|
-
// The email adapter
|
|
321
|
+
// Set email verification token validity to 2 hours
|
|
322
|
+
emailVerifyTokenValidityDuration: 2 * 60 * 60,
|
|
323
|
+
|
|
324
|
+
// Set email adapter
|
|
293
325
|
emailAdapter: {
|
|
294
|
-
module: '
|
|
326
|
+
module: 'example-mail-adapter',
|
|
295
327
|
options: {
|
|
296
|
-
//
|
|
297
|
-
|
|
298
|
-
// Your domain from mailgun.com
|
|
299
|
-
domain: 'example.com',
|
|
300
|
-
// Your API key from mailgun.com
|
|
301
|
-
apiKey: 'key-mykey',
|
|
328
|
+
// Additional adapter options
|
|
329
|
+
...mailAdapterOptions
|
|
302
330
|
}
|
|
303
331
|
},
|
|
304
|
-
|
|
305
|
-
// account lockout policy setting (OPTIONAL) - defaults to undefined
|
|
306
|
-
// if the account lockout policy is set and there are more than `threshold` number of failed login attempts then the `login` api call returns error code `Parse.Error.OBJECT_NOT_FOUND` with error message `Your account is locked due to multiple failed login attempts. Please try again after <duration> minute(s)`. After `duration` minutes of no login attempts, the application will allow the user to try login again.
|
|
307
|
-
accountLockout: {
|
|
308
|
-
duration: 5, // duration policy setting determines the number of minutes that a locked-out account remains locked out before automatically becoming unlocked. Set it to a value greater than 0 and less than 100000.
|
|
309
|
-
threshold: 3, // threshold policy setting determines the number of failed sign-in attempts that will cause a user account to be locked. Set it to an integer value greater than 0 and less than 1000.
|
|
310
|
-
},
|
|
311
|
-
// optional settings to enforce password policies
|
|
312
|
-
passwordPolicy: {
|
|
313
|
-
// Two optional settings to enforce strong passwords. Either one or both can be specified.
|
|
314
|
-
// If both are specified, both checks must pass to accept the password
|
|
315
|
-
// 1. a RegExp object or a regex string representing the pattern to enforce
|
|
316
|
-
validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/, // enforce password with at least 8 char with at least 1 lower case, 1 upper case and 1 digit
|
|
317
|
-
// 2. a callback function to be invoked to validate the password
|
|
318
|
-
validatorCallback: (password) => { return validatePassword(password) },
|
|
319
|
-
validationError: 'Password must contain at least 1 digit.' // optional error message to be sent instead of the default "Password does not meet the Password Policy requirements." message.
|
|
320
|
-
doNotAllowUsername: true, // optional setting to disallow username in passwords
|
|
321
|
-
maxPasswordAge: 90, // optional setting in days for password expiry. Login fails if user does not reset the password within this period after signup/last reset.
|
|
322
|
-
maxPasswordHistory: 5, // optional setting to prevent reuse of previous n passwords. Maximum value that can be specified is 20. Not specifying it or specifying 0 will not enforce history.
|
|
323
|
-
//optional setting to set a validity duration for password reset links (in seconds)
|
|
324
|
-
resetTokenValidityDuration: 24*60*60, // expire after 24 hours
|
|
325
|
-
}
|
|
326
332
|
});
|
|
327
333
|
```
|
|
328
334
|
|
|
329
|
-
|
|
330
|
-
- [parse-
|
|
335
|
+
Email adapters contributed by the community:
|
|
336
|
+
- [parse-server-api-mail-adapter](https://www.npmjs.com/package/parse-server-api-mail-adapter) (localization, templates, universally supports any email provider)
|
|
337
|
+
- [parse-smtp-template](https://www.npmjs.com/package/parse-smtp-template) (localization, templates)
|
|
331
338
|
- [parse-server-postmark-adapter](https://www.npmjs.com/package/parse-server-postmark-adapter)
|
|
332
339
|
- [parse-server-sendgrid-adapter](https://www.npmjs.com/package/parse-server-sendgrid-adapter)
|
|
333
340
|
- [parse-server-mandrill-adapter](https://www.npmjs.com/package/parse-server-mandrill-adapter)
|
|
@@ -338,7 +345,91 @@ You can also use other email adapters contributed by the community such as:
|
|
|
338
345
|
- [simple-parse-smtp-adapter](https://www.npmjs.com/package/simple-parse-smtp-adapter)
|
|
339
346
|
- [parse-server-generic-email-adapter](https://www.npmjs.com/package/parse-server-generic-email-adapter)
|
|
340
347
|
|
|
341
|
-
|
|
348
|
+
## Password and Account Policy
|
|
349
|
+
|
|
350
|
+
Set a password and account policy that meets your security requirements. The following is an example configuration. See the [Parse Server Options](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html) for more details and a full list of available options.
|
|
351
|
+
|
|
352
|
+
```js
|
|
353
|
+
const server = ParseServer({
|
|
354
|
+
...otherOptions,
|
|
355
|
+
|
|
356
|
+
// The account lock policy
|
|
357
|
+
accountLockout: {
|
|
358
|
+
// Lock the account for 5 minutes.
|
|
359
|
+
duration: 5,
|
|
360
|
+
// Lock an account after 3 failed log-in attempts
|
|
361
|
+
threshold: 3,
|
|
362
|
+
// Unlock the account after a successful password reset
|
|
363
|
+
unlockOnPasswordReset: true,
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
// The password policy
|
|
367
|
+
passwordPolicy: {
|
|
368
|
+
// Enforce a password of at least 8 characters which contain at least 1 lower case, 1 upper case and 1 digit
|
|
369
|
+
validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/,
|
|
370
|
+
// Do not allow the username as part of the password
|
|
371
|
+
doNotAllowUsername: true,
|
|
372
|
+
// Do not allow to re-use the last 5 passwords when setting a new password
|
|
373
|
+
maxPasswordHistory: 5,
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## Custom Routes
|
|
379
|
+
**Caution, this is an experimental feature that may not be appropriate for production.**
|
|
380
|
+
|
|
381
|
+
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:
|
|
382
|
+
|
|
383
|
+
### Example
|
|
384
|
+
|
|
385
|
+
```js
|
|
386
|
+
const api = new ParseServer({
|
|
387
|
+
...otherOptions,
|
|
388
|
+
|
|
389
|
+
pages: {
|
|
390
|
+
enableRouter: true, // Enables the experimental feature; required for custom routes
|
|
391
|
+
customRoutes: [{
|
|
392
|
+
method: 'GET',
|
|
393
|
+
path: 'custom_route',
|
|
394
|
+
handler: async request => {
|
|
395
|
+
// custom logic
|
|
396
|
+
// ...
|
|
397
|
+
// then, depending on the outcome, return a HTML file as response
|
|
398
|
+
return { file: 'custom_page.html' };
|
|
399
|
+
}
|
|
400
|
+
}]
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
The above route can be invoked by sending a `GET` request to:
|
|
406
|
+
`https://[parseServerPublicUrl]/[parseMount]/[pagesEndpoint]/[appId]/[customRoute]`
|
|
407
|
+
|
|
408
|
+
The `handler` receives the `request` and returns a `custom_page.html` webpage from the `pages.pagesPath` directory as response. The advantage of building a custom route this way is that it automatically makes use of Parse Server's built-in capabilities, such as [page localization](#pages) and [dynamic placeholders](#dynamic-placeholders).
|
|
409
|
+
|
|
410
|
+
### Reserved Paths
|
|
411
|
+
The following paths are already used by Parse Server's built-in features and are therefore not available for custom routes. Custom routes with an identical combination of `path` and `method` are ignored.
|
|
412
|
+
|
|
413
|
+
| Path | HTTP Method | Feature |
|
|
414
|
+
|-----------------------------|-------------|--------------------|
|
|
415
|
+
| `verify_email` | `GET` | email verification |
|
|
416
|
+
| `resend_verification_email` | `POST` | email verification |
|
|
417
|
+
| `choose_password` | `GET` | password reset |
|
|
418
|
+
| `request_password_reset` | `GET` | password reset |
|
|
419
|
+
| `request_password_reset` | `POST` | password reset |
|
|
420
|
+
|
|
421
|
+
### Parameters
|
|
422
|
+
|
|
423
|
+
| Parameter | Optional | Type | Default value | Example values | Environment variable | Description |
|
|
424
|
+
|------------------------------|----------|-----------------|---------------|-----------------------|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
425
|
+
| `pages` | yes | `Object` | `undefined` | - | `PARSE_SERVER_PAGES` | The options for pages such as password reset and email verification. |
|
|
426
|
+
| `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.** |
|
|
427
|
+
| `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. |
|
|
428
|
+
| `pages.customRoutes.method` | | `String` | - | `GET`, `POST` | - | The HTTP method of the custom route. |
|
|
429
|
+
| `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. |
|
|
430
|
+
| `pages.customRoutes.handler` | | `AsyncFunction` | - | `async () => { ... }` | - | The route handler that is invoked when the route matches the HTTP request. If the handler does not return a page, the request is answered with a 404 `Not found.` response. |
|
|
431
|
+
|
|
432
|
+
## Custom Pages
|
|
342
433
|
|
|
343
434
|
It’s possible to change the default pages of the app and redirect the user to another path or domain.
|
|
344
435
|
|
|
@@ -359,7 +450,7 @@ var server = ParseServer({
|
|
|
359
450
|
})
|
|
360
451
|
```
|
|
361
452
|
|
|
362
|
-
|
|
453
|
+
## Using Environment Variables
|
|
363
454
|
|
|
364
455
|
You may configure the Parse Server using environment variables:
|
|
365
456
|
|
|
@@ -380,15 +471,15 @@ $ PORT=8080 parse-server --appId APPLICATION_ID --masterKey MASTER_KEY
|
|
|
380
471
|
|
|
381
472
|
For the full list of configurable environment variables, run `parse-server --help` or take a look at [Parse Server Configuration](https://github.com/parse-community/parse-server/blob/master/src/Options/Definitions.js).
|
|
382
473
|
|
|
383
|
-
|
|
474
|
+
## Available Adapters
|
|
384
475
|
|
|
385
|
-
All official adapters are distributed as scoped
|
|
476
|
+
All official adapters are distributed as scoped packages on [npm (@parse)](https://www.npmjs.com/search?q=scope%3Aparse).
|
|
386
477
|
|
|
387
478
|
Some well maintained adapters are also available on the [Parse Server Modules](https://github.com/parse-server-modules) organization.
|
|
388
479
|
|
|
389
480
|
You can also find more adapters maintained by the community by searching on [npm](https://www.npmjs.com/search?q=parse-server%20adapter&page=1&ranking=optimal).
|
|
390
481
|
|
|
391
|
-
|
|
482
|
+
## Configuring File Adapters
|
|
392
483
|
|
|
393
484
|
Parse Server allows developers to choose from several options when hosting files:
|
|
394
485
|
|
|
@@ -398,19 +489,19 @@ Parse Server allows developers to choose from several options when hosting files
|
|
|
398
489
|
|
|
399
490
|
`GridFSBucketAdapter` is used by default and requires no setup, but if you're interested in using S3 or Google Cloud Storage, additional configuration information is available in the [Parse Server guide](http://docs.parseplatform.org/parse-server/guide/#configuring-file-adapters).
|
|
400
491
|
|
|
401
|
-
|
|
492
|
+
## Idempotency Enforcement
|
|
402
493
|
|
|
403
494
|
**Caution, this is an experimental feature that may not be appropriate for production.**
|
|
404
495
|
|
|
405
|
-
This feature deduplicates identical requests that are received by Parse Server
|
|
496
|
+
This feature deduplicates identical requests that are received by Parse Server multiple times, typically due to network issues or network adapter access restrictions on mobile operating systems.
|
|
406
497
|
|
|
407
|
-
Identical requests are identified by their request header `X-Parse-Request-Id`. Therefore a client request has to include this header for deduplication to be applied. Requests that do not contain this header cannot be deduplicated and are processed normally by Parse Server. This means rolling out this feature to clients is seamless as Parse Server still processes
|
|
498
|
+
Identical requests are identified by their request header `X-Parse-Request-Id`. Therefore a client request has to include this header for deduplication to be applied. Requests that do not contain this header cannot be deduplicated and are processed normally by Parse Server. This means rolling out this feature to clients is seamless as Parse Server still processes requests without this header when this feature is enabled.
|
|
408
499
|
|
|
409
500
|
> This feature needs to be enabled on the client side to send the header and on the server to process the header. Refer to the specific Parse SDK docs to see whether the feature is supported yet.
|
|
410
501
|
|
|
411
502
|
Deduplication is only done for object creation and update (`POST` and `PUT` requests). Deduplication is not done for object finding and deletion (`GET` and `DELETE` requests), as these operations are already idempotent by definition.
|
|
412
503
|
|
|
413
|
-
|
|
504
|
+
### Configuration example <!-- omit in toc -->
|
|
414
505
|
```
|
|
415
506
|
let api = new ParseServer({
|
|
416
507
|
idempotencyOptions: {
|
|
@@ -419,19 +510,217 @@ let api = new ParseServer({
|
|
|
419
510
|
}
|
|
420
511
|
}
|
|
421
512
|
```
|
|
422
|
-
|
|
513
|
+
### Parameters <!-- omit in toc -->
|
|
423
514
|
|
|
424
|
-
| Parameter
|
|
425
|
-
|
|
426
|
-
| `idempotencyOptions`
|
|
427
|
-
| `idempotencyOptions.paths
|
|
428
|
-
| `idempotencyOptions.ttl`
|
|
515
|
+
| Parameter | Optional | Type | Default value | Example values | Environment variable | Description |
|
|
516
|
+
|----------------------------|----------|-----------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
517
|
+
| `idempotencyOptions` | yes | `Object` | `undefined` | | PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_OPTIONS | Setting this enables idempotency enforcement for the specified paths. |
|
|
518
|
+
| `idempotencyOptions.paths` | yes | `Array<String>` | `[]` | `.*` (all paths, includes the examples below), <br>`functions/.*` (all functions), <br>`jobs/.*` (all jobs), <br>`classes/.*` (all classes), <br>`functions/.*` (all functions), <br>`users` (user creation / update), <br>`installations` (installation creation / update) | PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_PATHS | An array of path patterns that have to match the request path for request deduplication to be enabled. The mount path must not be included, for example to match the request path `/parse/functions/myFunction` specify the path pattern `functions/myFunction`. A trailing slash of the request path is ignored, for example the path pattern `functions/myFunction` matches both `/parse/functions/myFunction` and `/parse/functions/myFunction/`. |
|
|
519
|
+
| `idempotencyOptions.ttl` | yes | `Integer` | `300` | `60` (60 seconds) | PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_TTL | The duration in seconds after which a request record is discarded from the database. Duplicate requests due to network issues can be expected to arrive within milliseconds up to several seconds. This value must be greater than `0`. |
|
|
429
520
|
|
|
430
|
-
|
|
521
|
+
### Notes <!-- omit in toc -->
|
|
431
522
|
|
|
432
523
|
- This feature is currently only available for MongoDB and not for Postgres.
|
|
433
524
|
|
|
434
|
-
|
|
525
|
+
## Localization
|
|
526
|
+
|
|
527
|
+
### Pages
|
|
528
|
+
**Caution, this is an experimental feature that may not be appropriate for production.**
|
|
529
|
+
|
|
530
|
+
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:
|
|
531
|
+
|
|
532
|
+
```js
|
|
533
|
+
const api = new ParseServer({
|
|
534
|
+
...otherOptions,
|
|
535
|
+
|
|
536
|
+
pages: {
|
|
537
|
+
enableRouter: true, // Enables the experimental feature; required for localization
|
|
538
|
+
enableLocalization: true,
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
Localization is achieved by matching a request-supplied `locale` parameter with localized page content. The locale can be supplied in either the request query, body or header with the following keys:
|
|
544
|
+
- query: `locale`
|
|
545
|
+
- body: `locale`
|
|
546
|
+
- header: `x-parse-page-param-locale`
|
|
547
|
+
|
|
548
|
+
For example, a password reset link with the locale parameter in the query could look like this:
|
|
549
|
+
```
|
|
550
|
+
http://example.com/parse/apps/[appId]/request_password_reset?token=[token]&username=[username]&locale=de-AT
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
- Localization is only available for pages in the pages directory as set with `pages.pagesPath`.
|
|
554
|
+
- Localization for feature pages (e.g. password reset, email verification) is disabled if `pages.customUrls` are set, even if the custom URLs point to the pages within the pages path.
|
|
555
|
+
- Only `.html` files are considered for localization when localizing custom pages.
|
|
556
|
+
|
|
557
|
+
Pages can be localized in two ways:
|
|
558
|
+
|
|
559
|
+
#### Localization with Directory Structure
|
|
560
|
+
|
|
561
|
+
Pages are localized by using the corresponding file in the directory structure where the files are placed in subdirectories named after the locale or language. The file in the base directory is the default file.
|
|
562
|
+
|
|
563
|
+
**Example Directory Structure:**
|
|
564
|
+
```js
|
|
565
|
+
root/
|
|
566
|
+
├── public/ // pages base path
|
|
567
|
+
│ ├── example.html // default file
|
|
568
|
+
│ └── de/ // de language folder
|
|
569
|
+
│ │ └── example.html // de localized file
|
|
570
|
+
│ └── de-AT/ // de-AT locale folder
|
|
571
|
+
│ │ └── example.html // de-AT localized file
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
Files are matched with the locale in the following order:
|
|
575
|
+
1. Locale match, e.g. locale `de-AT` matches file in folder `de-AT`.
|
|
576
|
+
1. Language match, e.g. locale `de-CH` matches file in folder `de`.
|
|
577
|
+
1. Default; file in base folder is returned.
|
|
578
|
+
|
|
579
|
+
**Configuration Example:**
|
|
580
|
+
```js
|
|
581
|
+
const api = new ParseServer({
|
|
582
|
+
...otherOptions,
|
|
583
|
+
|
|
584
|
+
pages: {
|
|
585
|
+
enableRouter: true, // Enables the experimental feature; required for localization
|
|
586
|
+
enableLocalization: true,
|
|
587
|
+
customUrls: {
|
|
588
|
+
passwordReset: 'https://example.com/page.html'
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
Pros:
|
|
595
|
+
- All files are complete in their content and can be easily opened and previewed by viewing the file in a browser.
|
|
596
|
+
|
|
597
|
+
Cons:
|
|
598
|
+
- In most cases, a localized page differs only slightly from the default page, which could cause a lot of duplicate code that is difficult to maintain.
|
|
599
|
+
|
|
600
|
+
#### Localization with JSON Resource
|
|
601
|
+
|
|
602
|
+
Pages are localized by adding placeholders in the HTML files and providing a JSON resource that contains the translations to fill into the placeholders.
|
|
603
|
+
|
|
604
|
+
**Example Directory Structure:**
|
|
605
|
+
```js
|
|
606
|
+
root/
|
|
607
|
+
├── public/ // pages base path
|
|
608
|
+
│ ├── example.html // the page containing placeholders
|
|
609
|
+
├── private/ // folder outside of public scope
|
|
610
|
+
│ └── translations.json // JSON resource file
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
The JSON resource file loosely follows the [i18next](https://github.com/i18next/i18next) syntax, which is a syntax that is often supported by translation platforms, making it easy to manage translations, exporting them for use in Parse Server, and even to automate this workflow.
|
|
614
|
+
|
|
615
|
+
**Example JSON Content:**
|
|
616
|
+
```json
|
|
617
|
+
{
|
|
618
|
+
"en": { // resource for language `en` (English)
|
|
619
|
+
"translation": {
|
|
620
|
+
"greeting": "Hello!"
|
|
621
|
+
}
|
|
622
|
+
},
|
|
623
|
+
"de": { // resource for language `de` (German)
|
|
624
|
+
"translation": {
|
|
625
|
+
"greeting": "Hallo!"
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
"de-AT": { // resource for locale `de-AT` (Austrian German)
|
|
629
|
+
"translation": {
|
|
630
|
+
"greeting": "Servus!"
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
**Configuration Example:**
|
|
637
|
+
```js
|
|
638
|
+
const api = new ParseServer({
|
|
639
|
+
...otherOptions,
|
|
640
|
+
|
|
641
|
+
pages: {
|
|
642
|
+
enableRouter: true, // Enables the experimental feature; required for localization
|
|
643
|
+
enableLocalization: true,
|
|
644
|
+
localizationJsonPath: './private/localization.json',
|
|
645
|
+
localizationFallbackLocale: 'en'
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
Pros:
|
|
651
|
+
- There is only one HTML file to maintain that contains the placeholders that are filled with the translations according to the locale.
|
|
652
|
+
|
|
653
|
+
Cons:
|
|
654
|
+
- Files cannot be easily previewed by viewing the file in a browser because the content contains only placeholders and even HTML or CSS changes may be dynamically applied, e.g. when a localization requires a Right-To-Left layout direction.
|
|
655
|
+
- Style and other fundamental layout changes may be more difficult to apply.
|
|
656
|
+
|
|
657
|
+
#### Dynamic placeholders
|
|
658
|
+
|
|
659
|
+
In addition to feature related default parameters such as `appId` and the translations provided via JSON resource, it is possible to define custom dynamic placeholders as part of the router configuration. This works independently of localization and, also if `enableLocalization` is disabled.
|
|
660
|
+
|
|
661
|
+
**Configuration Example:**
|
|
662
|
+
```js
|
|
663
|
+
const api = new ParseServer({
|
|
664
|
+
...otherOptions,
|
|
665
|
+
|
|
666
|
+
pages: {
|
|
667
|
+
enableRouter: true, // Enables the experimental feature; required for localization
|
|
668
|
+
placeholders: {
|
|
669
|
+
exampleKey: 'exampleValue'
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
```
|
|
674
|
+
The placeholders can also be provided as function or as async function, with the `locale` and other feature related parameters passed through, to allow for dynamic placeholder values:
|
|
675
|
+
|
|
676
|
+
```js
|
|
677
|
+
const api = new ParseServer({
|
|
678
|
+
...otherOptions,
|
|
679
|
+
|
|
680
|
+
pages: {
|
|
681
|
+
enableRouter: true, // Enables the experimental feature; required for localization
|
|
682
|
+
placeholders: async (params) => {
|
|
683
|
+
const value = await doSomething(params.locale);
|
|
684
|
+
return {
|
|
685
|
+
exampleKey: value
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
#### Reserved Keys
|
|
693
|
+
|
|
694
|
+
The following parameter and placeholder keys are reserved because they are used related to features such as password reset or email verification. They should not be used as translation keys in the JSON resource or as manually defined placeholder keys in the configuration: `appId`, `appName`, `email`, `error`, `locale`, `publicServerUrl`, `token`, `username`.
|
|
695
|
+
|
|
696
|
+
#### Parameters
|
|
697
|
+
|
|
698
|
+
| Parameter | Optional | Type | Default value | Example values | Environment variable | Description |
|
|
699
|
+
|-------------------------------------------------|----------|---------------------------------------|----------------------------------------|------------------------------------------------------|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
700
|
+
| `pages` | yes | `Object` | `undefined` | - | `PARSE_SERVER_PAGES` | The options for pages such as password reset and email verification. |
|
|
701
|
+
| `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.** |
|
|
702
|
+
| `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. |
|
|
703
|
+
| `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. |
|
|
704
|
+
| `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. |
|
|
705
|
+
| `pages.placeholders` | yes | `Object`, `Function`, `AsyncFunction` | `undefined` | `{ exampleKey: 'exampleValue' }` | `PARSE_SERVER_PAGES_PLACEHOLDERS` | The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function. |
|
|
706
|
+
| `pages.forceRedirect` | yes | `Boolean` | `false` | - | `PARSE_SERVER_PAGES_FORCE_REDIRECT` | 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). |
|
|
707
|
+
| `pages.pagesPath` | yes | `String` | `./public` | `./files/pages`, `../../pages` | `PARSE_SERVER_PAGES_PAGES_PATH` | The path to the pages directory; this also defines where the static endpoint `/apps` points to. |
|
|
708
|
+
| `pages.pagesEndpoint` | yes | `String` | `apps` | - | `PARSE_SERVER_PAGES_PAGES_ENDPOINT` | The API endpoint for the pages. |
|
|
709
|
+
| `pages.customUrls` | yes | `Object` | `{}` | `{ passwordReset: 'https://example.com/page.html' }` | `PARSE_SERVER_PAGES_CUSTOM_URLS` | The URLs to the custom pages |
|
|
710
|
+
| `pages.customUrls.passwordReset` | yes | `String` | `password_reset.html` | - | `PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET` | The URL to the custom page for password reset. |
|
|
711
|
+
| `pages.customUrls.passwordResetSuccess` | yes | `String` | `password_reset_success.html` | - | `PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET_SUCCESS` | The URL to the custom page for password reset -> success. |
|
|
712
|
+
| `pages.customUrls.passwordResetLinkInvalid` | yes | `String` | `password_reset_link_invalid.html` | - | `PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET_LINK_INVALID` | The URL to the custom page for password reset -> link invalid. |
|
|
713
|
+
| `pages.customUrls.emailVerificationSuccess` | yes | `String` | `email_verification_success.html` | - | `PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SUCCESS` | The URL to the custom page for email verification -> success. |
|
|
714
|
+
| `pages.customUrls.emailVerificationSendFail` | yes | `String` | `email_verification_send_fail.html` | - | `PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SEND_FAIL` | The URL to the custom page for email verification -> link send fail. |
|
|
715
|
+
| `pages.customUrls.emailVerificationSendSuccess` | yes | `String` | `email_verification_send_success.html` | - | `PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SEND_SUCCESS` | The URL to the custom page for email verification -> resend link -> success. |
|
|
716
|
+
| `pages.customUrls.emailVerificationLinkInvalid` | yes | `String` | `email_verification_link_invalid.html` | - | `PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_LINK_INVALID` | The URL to the custom page for email verification -> link invalid. |
|
|
717
|
+
| `pages.customUrls.emailVerificationLinkExpired` | yes | `String` | `email_verification_link_expired.html` | - | `PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_LINK_EXPIRED` | The URL to the custom page for email verification -> link expired. |
|
|
718
|
+
|
|
719
|
+
### Notes <!-- omit in toc -->
|
|
720
|
+
|
|
721
|
+
- In combination with the [Parse Server API Mail Adapter](https://www.npmjs.com/package/parse-server-api-mail-adapter) Parse Server provides a fully localized flow (emails -> pages) for the user. The email adapter sends a localized email and adds a locale parameter to the password reset or email verification link, which is then used to respond with localized pages.
|
|
722
|
+
|
|
723
|
+
## Logging
|
|
435
724
|
|
|
436
725
|
Parse Server will, by default, log:
|
|
437
726
|
* to the console
|
|
@@ -441,13 +730,17 @@ Logs are also viewable in Parse Dashboard.
|
|
|
441
730
|
|
|
442
731
|
**Want to log each request and response?** Set the `VERBOSE` environment variable when starting `parse-server`. Usage :- `VERBOSE='1' parse-server --appId APPLICATION_ID --masterKey MASTER_KEY`
|
|
443
732
|
|
|
444
|
-
**Want logs to be
|
|
733
|
+
**Want logs to be placed in a different folder?** Pass the `PARSE_SERVER_LOGS_FOLDER` environment variable when starting `parse-server`. Usage :- `PARSE_SERVER_LOGS_FOLDER='<path-to-logs-folder>' parse-server --appId APPLICATION_ID --masterKey MASTER_KEY`
|
|
445
734
|
|
|
446
735
|
**Want to log specific levels?** Pass the `logLevel` parameter when starting `parse-server`. Usage :- `parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --logLevel LOG_LEVEL`
|
|
447
736
|
|
|
448
737
|
**Want new line delimited JSON error logs (for consumption by CloudWatch, Google Cloud Logging, etc)?** Pass the `JSON_LOGS` environment variable when starting `parse-server`. Usage :- `JSON_LOGS='1' parse-server --appId APPLICATION_ID --masterKey MASTER_KEY`
|
|
449
738
|
|
|
450
|
-
#
|
|
739
|
+
# Deprecations
|
|
740
|
+
|
|
741
|
+
See the [Deprecation Plan](https://github.com/parse-community/parse-server/blob/master/DEPRECATIONS.md) for an overview of deprecations and planned breaking changes.
|
|
742
|
+
|
|
743
|
+
# Live Query
|
|
451
744
|
|
|
452
745
|
Live queries are meant to be used in real-time reactive applications, where just using the traditional query paradigm could cause several problems, like increased response time and high network and server usage. Live queries should be used in cases where you need to continuously update a page with fresh data coming from the database, which often happens in (but is not limited to) online games, messaging clients and shared to-do lists.
|
|
453
746
|
|
|
@@ -484,13 +777,13 @@ $ docker build --tag parse-server .
|
|
|
484
777
|
$ docker run --name my-mongo -d mongo
|
|
485
778
|
```
|
|
486
779
|
|
|
487
|
-
#### Running the Parse Server Image
|
|
780
|
+
#### Running the Parse Server Image <!-- omit in toc -->
|
|
488
781
|
|
|
489
782
|
```bash
|
|
490
783
|
$ docker run --name my-parse-server --link my-mongo:mongo -v config-vol:/parse-server/config -p 1337:1337 -d parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongodb://mongo/test --publicServerURL http://localhost:1337/parse --mountGraphQL --mountPlayground
|
|
491
784
|
```
|
|
492
785
|
|
|
493
|
-
***Note:*** *If you want to use [Cloud Code](https://docs.parseplatform.org/cloudcode/guide/)
|
|
786
|
+
***Note:*** *If you want to use [Cloud Code](https://docs.parseplatform.org/cloudcode/guide/), add `-v cloud-code-vol:/parse-server/cloud --cloud /parse-server/cloud/main.js` to the command above. Make sure `main.js` is in the `cloud-code-vol` directory before starting Parse Server.*
|
|
494
787
|
|
|
495
788
|
After starting the server, you can visit http://localhost:1337/playground in your browser to start playing with your GraphQL API.
|
|
496
789
|
|
|
@@ -731,7 +1024,7 @@ To start creating your custom schema, you need to code a `schema.graphql` file a
|
|
|
731
1024
|
$ parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongodb://localhost/test --publicServerURL http://localhost:1337/parse --cloud ./cloud/main.js --graphQLSchema ./cloud/schema.graphql --mountGraphQL --mountPlayground
|
|
732
1025
|
```
|
|
733
1026
|
|
|
734
|
-
### Creating your first custom query
|
|
1027
|
+
### Creating your first custom query <!-- omit in toc -->
|
|
735
1028
|
|
|
736
1029
|
Use the code below for your `schema.graphql` and `main.js` files. Then restart your Parse Server.
|
|
737
1030
|
|
|
@@ -793,7 +1086,7 @@ directly on this branch:
|
|
|
793
1086
|
npm install parse-community/parse-server.git#master
|
|
794
1087
|
```
|
|
795
1088
|
|
|
796
|
-
## Experimenting
|
|
1089
|
+
## Experimenting <!-- omit in toc -->
|
|
797
1090
|
|
|
798
1091
|
You can also use your own forks, and work in progress branches by specifying them:
|
|
799
1092
|
|
|
@@ -857,3 +1150,7 @@ Support us with a monthly donation and help us continue our activities. [Become
|
|
|
857
1150
|
-----
|
|
858
1151
|
|
|
859
1152
|
As of April 5, 2017, Parse, LLC has transferred this code to the parse-community organization, and will no longer be contributing to or distributing this code.
|
|
1153
|
+
|
|
1154
|
+
[license-svg]: https://img.shields.io/badge/license-BSD-lightgrey.svg
|
|
1155
|
+
[license-link]: LICENSE
|
|
1156
|
+
[open-collective-link]: https://opencollective.com/parse-server
|