@flowerforce/flowerbase 1.0.1-beta.12 → 1.0.1-beta.14

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 CHANGED
@@ -1,18 +1,420 @@
1
1
  # flowerbase
2
2
 
3
- > **A serverless-native MongoDB package designed for modern cloud applications. Lightweight. Fast. Pay-as-you-go.**
3
+ > **A serverless-native MongoDB package designed for modern cloud applications**
4
+
5
+ Unlike MongoDB Realm or other cloud platforms, we do not offer a graphical interface where you can configure services through a dashboard.
6
+ Instead, everything is code-based and developer-driven, offering full flexibility through configuration files and source code.
7
+
8
+ This documentation is structured to guide both experienced Realm users and newcomers alike — whether you’re migrating or starting clean.
9
+
10
+ #### 🧠 Features Summary
11
+ | Feature | Status |
12
+ |--------------------------|-----------------------------------------|
13
+ | Realm-compatible schema | ✅ Supported (unchanged) |
14
+ | Authentication strategy | ✅ Local Email/Password only |
15
+ | OAuth / API Keys / etc. | 🚫 Not supported (for now) |
16
+ | User data accessibility | ✅ Stored in your main DB |
17
+ | Device Sync | 🚫 Not supported (for now) |
18
+ | Functions | ✅ Supported (unchanged) |
19
+ | Triggers | ✅ Supported (unchanged) |
20
+ | HTTP Endpoints | ✅ Supported (unchanged) |
21
+
22
+
23
+
24
+ > ⚠️ **Already have an existing Realm project?**
25
+ > You can skip ahead to the [Migration Guide](#migration) to quickly adapt your project to Flowerbase.
26
+
27
+
28
+ ## 🚀 Creating a New Project from Scratch
29
+
30
+ If you're starting fresh, you’ll learn how to:
31
+
32
+ - Scaffold a minimal Node.js + TypeScript backend
33
+ - Install and configure `@flowerforce/flowerbase`
34
+ - Set up authentication, data models, rules, and custom logic
35
+ - Deploy your app and connect it to any frontend (React, Vue, mobile, etc.)
36
+
37
+ ## 📁 1. Project Setup
38
+
39
+ ### ✅ Step 1.1 – Initialize a Node.js Application
40
+
41
+ Create a new project directory and initialize it with npm:
42
+
43
+ ```bash
44
+ mkdir my-app
45
+ cd my-app
46
+ npm init -y
47
+ ```
48
+
49
+ ### ✅ Step 1.2 – Install Dependencies
50
+ Install the `@flowerforce/flowerbase` library, which provides the tools required for managing your data with MongoDB Atlas:
51
+
52
+ ```bash
53
+ npm install @flowerforce/flowerbase
54
+ ```
55
+
56
+ ## 🏗️ 2. Create the Project Structure
57
+ Inside your project root, create the main source directory:
58
+
59
+ ```bash
60
+ mkdir src
61
+ ```
62
+ Within the src folder, add a new file named index.ts:
63
+
64
+ ```bash
65
+ touch src/index.ts
66
+ ```
67
+
68
+ ## 🌿 3. Environment Variables
69
+ Ensure the following environment variables are set in your .env file or deployment environment:
70
+
71
+
72
+ | Variable | Description | Example |
73
+ | ---------------------- | --------------------------------------------------------------------------- | -------------------------------------------------- |
74
+ | `PROJECT_ID` | A unique ID to identify your project. This value can be freely invented — it's preserved mainly for compatibility with the old Realm-style project structure. | `my-flowerbase-app` |
75
+ | `PORT` | The port on which the server will run. | `3000` |
76
+ | `DB_CONNECTION_STRING` | MongoDB connection URI, including username, password, and database name. | `mongodb+srv://user:pass@cluster.mongodb.net/mydb` |
77
+ | `APP_SECRET` | Secret used to sign and verify JWT tokens (choose a strong secret). | `supersecretkey123!` |
78
+ | `HOST` | The host address the server binds to (usually `0.0.0.0` for public access). | `0.0.0.0` |
79
+
80
+
81
+ Example:
82
+ ```env
83
+ PROJECT_ID=your-project-id
84
+ PORT=3000
85
+ DB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongodb.net/dbname
86
+ APP_SECRET=your-jwt-secret
87
+ HOST=0.0.0.0
88
+ ```
89
+
90
+ 🛡️ Note: Never commit .env files to source control. Use a .gitignore file to exclude it.
91
+
92
+
93
+ ## 🧩 4. Initialize Flowerbase
94
+ In your index.ts file, import the initialize function from the `@flowerforce/flowerbase` package and invoke it:
95
+
96
+ ```ts
97
+ // src/index.ts
98
+
99
+ import { initialize } from '@flowerforce/flowerbase';
100
+
101
+ initialize({
102
+ projectId: process.env.PROJECT_ID,
103
+ port: Number(process.env.PORT),
104
+ mongodbUrl: process.env.DB_CONNECTION_STRING,
105
+ jwtSecret: process.env.APP_SECRET,
106
+ host: process.env.HOST
107
+ });
108
+ ```
109
+
110
+ This initializes the Flowerbase integration, connecting your application to MongoDB Atlas.
111
+
112
+ ## 🛠️ 5. Server Configuration – Authentication, Rules, and Functions
113
+ After setting up the base Flowerbase integration, you can now configure advanced features to control how your backend behaves.
114
+
115
+ ### 📁 Suggested Folder Structure
116
+
117
+ ```code
118
+ 📁 my-app/
119
+ |
120
+ ├── 📁 src/
121
+ | |
122
+ │ ├── 📄 index.ts
123
+ | |
124
+ │ ├── 📁 auth/
125
+ | | |
126
+ │ │ └── 📄 custom_user_data.json
127
+ | | |
128
+ │ │ └── 📄 providers.json
129
+ | |
130
+ │ ├── 📁 data_sources/
131
+ | | |
132
+ │ │ └── 📁 mongodb-atlas/
133
+ | | |
134
+ │ │ └── 📁 your_db_name/
135
+ | | |
136
+ │ │ └── 📁 collection1/
137
+ | | | |
138
+ │ │ | └── 📄 rules.json
139
+ │ │ |
140
+ │ │ └── 📁 collection2/
141
+ | | |
142
+ │ │ └── 📄 rules.json
143
+ │ │
144
+ │ ├── 📁 functions/
145
+ │ │ |
146
+ │ │ └── 📄 exampleFunction.ts
147
+ │ │ |
148
+ │ │ └── 📄 config.json
149
+ │ │
150
+ │ ├── 📁 triggers/
151
+ │ │ |
152
+ │ │ └── 📄 trigger1.json
153
+ │ │ |
154
+ │ │ └── 📄 trigger2.json
155
+ │ │
156
+ │ ├── 📁 http_endpoints/
157
+ │ │ |
158
+ │ │ └── 📄 config.json
159
+ │ │
160
+ └── 📄 .env
161
+ ```
162
+
163
+ #### 📖 Structure summary
164
+ | Area | Description | Link |
165
+ | ---------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
166
+ | 🧠 Functions | Overview of server-side functions in Realm | [Functions Documentation](https://www.mongodb.com/docs/atlas/app-services/functions/) |
167
+ | ⏰ Triggers | Triggers that run on database events or schedules | [Triggers Documentation](https://www.mongodb.com/docs/atlas/app-services/triggers/) |
168
+ | 👤 User Management | Managing users, authentication, and providers | [Users Documentation](https://www.mongodb.com/docs/atlas/app-services/users/) |
169
+ | 🌐 Custom Endpoints | HTTP endpoints to expose backend functionality via API | [Custom Endpoints](http://mongodb.com/docs/atlas/app-services/data-api/custom-endpoints/) |
170
+ | 🔐 Rules & Permissions | Define fine-grained access control for collections | [Rules Documentation](https://www.mongodb.com/docs/atlas/app-services/rules/) |
171
+
172
+
173
+ ## 🔐 6. Authentication – Local Email/Password (User-Pass)
174
+
175
+ The authentication system in `@flowerforce/flowerbase` reimplements the classic **email/password** login method (called local-userpass), similar to the one used by MongoDB Realm.
176
+
177
+ ### 🧱 Compatibility with Realm
178
+
179
+ In MongoDB Atlas (Realm), users were stored in a separate internal authentication database, not directly accessible via the standard MongoDB collections.
180
+
181
+ However, with Flowerbase:
182
+
183
+ - Users are stored directly in a MongoDB collection (by default named auth_users), but this can be customized in the server project via a JSON configuration file, as shown later in this guide.
184
+
185
+ - The document structure remains identical to the previous Realm implementation
186
+
187
+ - No changes are required to migrate the user data — existing user documents will continue to work as-is.
188
+ However, all users will be required to reset their passwords since it is not possible to extract passwords from the old MongoDB authentication system.
189
+
190
+ ### ✅ Supported Auth Method
191
+
192
+ The only authentication mode currently re-implemented in `@flowerforce/flowerbase` is:
193
+
194
+ - Local Email/Password (local-userpass)
195
+
196
+ > Other methods (OAuth, API key, anonymous, etc.) are not supported yet.
197
+
198
+ #### Example user:
199
+ ```js
200
+ {
201
+ "_id": ObjectId("2scgsb3gev99gsty2ev3g2g323d2hs"),
202
+ "email": "myuser@flowerbase.example",
203
+ "password": "your-encrypted-password",
204
+ "status": "confirmed",
205
+ "identities": [
206
+ {
207
+ "id": "example-id",
208
+ "provider_type": "local-userpass",
209
+ "provider_id": "example-provider-id",
210
+ "provider_data": {
211
+ "email": "myuser@flowerbase.example",
212
+ }
213
+ }
214
+ ]
215
+ }
216
+ ```
217
+
218
+ You can specify the MongoDB collection used to store authentication users by configuring the `auth_collection` field inside the `auth/providers.json` file.
219
+
220
+ #### 📁 auth/providers.json
221
+ Example
222
+ ```json
223
+ {
224
+ "api-key": {
225
+ "name": "api-key",
226
+ "type": "api-key",
227
+ "disabled": true
228
+ },
229
+ "local-userpass": {
230
+ "name": "local-userpass",
231
+ "type": "local-userpass",
232
+ "disabled": false,
233
+ "auth_collection": "my-users-collection" //custom collection name
234
+ "config": {
235
+ "autoConfirm": true,
236
+ "resetPasswordSubject": "reset",
237
+ "resetPasswordUrl": "https://my.app.url/password-reset",
238
+ "runConfirmationFunction": false
239
+ }
240
+ }
241
+ }
242
+
243
+ ```
244
+ If you're configuring the project from scratch, you can skip ahead to the [Build](#build) step.
245
+
246
+ --------
247
+
248
+
249
+ <a id="migration"></a>
250
+ ## 🔄 [Migration Guide](#migration) - Migrating Your Realm Project
251
+
252
+ Follow these steps to rebuild your backend in a clean and modern Node.js environment:
253
+
254
+ ## 🪜 Step-by-Step Migration
255
+
256
+ ### 📥 Download Your Realm App from MongoDB Atlas
257
+
258
+ Follow these steps to export and download your Realm app from MongoDB Cloud.
259
+
260
+ ---
261
+
262
+ #### 1. Log In to MongoDB Cloud
263
+
264
+ Go to [https://cloud.mongodb.com/](https://cloud.mongodb.com/) and sign in with your credentials.
4
265
 
5
266
  ---
6
267
 
7
- ## Features
268
+ #### 2. Select Your Project
8
269
 
9
- - 🚀 **Serverless-ready** built from the ground up to work in serverless environments like AWS Lambda.
10
- - 🔄 **MongoDB-compatible API** — drop-in replacement for most common MongoDB queries and models.
11
- - 🔐 **Secure by default** — Strict access rules.
270
+ From the dashboard, choose the **project** that contains the Realm app you want to download.
12
271
 
13
272
  ---
14
273
 
15
- ## 📦 Installation
274
+ #### 3. Open the Realm App List
275
+
276
+ - In the left-hand sidebar, under the **Services** section, click on **"Triggers"**.
277
+ - Then click the **"View All Apps"** button in the top-right corner.
278
+
279
+ ---
280
+
281
+ #### 4. Select the Desired App
282
+
283
+ From the list of applications, click on the **app name** you wish to export.
284
+
285
+ ---
286
+
287
+ #### 5. Go to Deployment
288
+
289
+ In the left sidebar, under the **Manage** section, click on **"Deployment"**.
290
+
291
+ ---
292
+
293
+ #### 6. Export the App
294
+
295
+ Click on the **"Export App"** tab at the top of the page.
296
+
297
+ ---
298
+
299
+ #### 7. Download the App
300
+
301
+ Scroll to the bottom and click the **"Download App"** button.
302
+
303
+ This will download a `.zip` file containing your Realm app's full structure and configuration.
304
+
305
+ ---
306
+
307
+ ✅ You are now ready to migrate or inspect your Realm app locally!
308
+
309
+ In your existing project folder, initialize a new Node.js project, Run:
310
+
311
+ ```bash
312
+ npm init -y
313
+ ```
314
+ Install Flowerbase
315
+
316
+ ```bash
317
+ npm install @flowerforce/flowerbase
318
+ ```
319
+ Create an index.ts file
320
+
321
+ Inside your project, create index.ts:
16
322
 
17
323
  ```bash
18
- npm install flowerbase
324
+ touch index.ts
325
+ ```
326
+
327
+ Initialize the Flowerbase App
328
+
329
+ In index.ts, add:
330
+
331
+ ```ts
332
+ import { initialize } from "@flowerforce/flowerbase";
333
+
334
+ initialize({
335
+ projectId: process.env.PROJECT_ID,
336
+ port: Number(process.env.PORT),
337
+ mongodbUrl: process.env.DB_CONNECTION_STRING,
338
+ jwtSecret: process.env.APP_SECRET,
339
+ host: process.env.HOST
340
+ });
341
+ ```
342
+
343
+ Ensure the following environment variables are set in your .env file or deployment environment:
344
+
345
+
346
+ | Variable | Description | Example |
347
+ | ---------------------- | --------------------------------------------------------------------------- | -------------------------------------------------- |
348
+ | `PROJECT_ID` | A unique ID to identify your project. This value can be freely invented — it's preserved mainly for compatibility with the old Realm-style project structure. | `my-flowerbase-app` |
349
+ | `PORT` | The port on which the server will run. | `3000` |
350
+ | `DB_CONNECTION_STRING` | MongoDB connection URI, including username, password, and database name. | `mongodb+srv://user:pass@cluster.mongodb.net/mydb` |
351
+ | `APP_SECRET` | Secret used to sign and verify JWT tokens (choose a strong secret). | `supersecretkey123!` |
352
+ | `HOST` | The host address the server binds to (usually `0.0.0.0` for public access). | `0.0.0.0` |
353
+
354
+
355
+ Example:
356
+ ```env
357
+ PROJECT_ID=your-project-id
358
+ PORT=3000
359
+ DB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongodb.net/dbname
360
+ APP_SECRET=your-jwt-secret
361
+ HOST=0.0.0.0
362
+ ```
363
+
364
+ 🛡️ Note: Never commit .env files to source control. Use a .gitignore file to exclude it.
365
+
366
+
367
+ <a id="build"></a>
368
+ ## 🚀 Build & Deploy the Server
369
+
370
+ Once your migration or first configuration is complete, it’s time to build and deploy the backend so it can be accessed by your frontend or external clients.
371
+
372
+ ### 🔧 Build the App
373
+
374
+ If you're using for example TypeScript:
375
+
376
+ ```bash
377
+ npx tsc
378
+ ```
379
+
380
+
381
+ You can deploy the application using any Node.js-compatible platform.
382
+ Once deployed, you'll receive a public URL (e.g. https://your-app-name.up.example.app).
383
+
384
+ >This URL should be used as the base URL in your frontend application, as explained in the next section.
385
+
386
+ ## 🌐 Frontend Setup – Realm SDK in React (Example)
387
+
388
+ You can use the official `realm-web` SDK to integrate MongoDB Realm into a React application.
389
+ This serves as a sample setup — similar logic can be applied using other official Realm SDKs **(e.g. React Native, Node, or Flutter)**.
390
+
391
+ ### 📦 Install Realm SDK
392
+
393
+ ```bash
394
+ npm install realm-web
395
+ ```
396
+
397
+ ### ⚙️ Configure Realm in React
398
+
399
+ Create a file to initialize and export the Realm App instance:
400
+
401
+ ```ts
402
+ // src/realm/realmApp.ts
403
+
404
+ import * as Realm from "realm-web";
405
+
406
+ // Replace with your actual Realm App ID and your deployed backend URL
407
+ const app = new Realm.App({
408
+ id: "your-realm-app-id", // e.g., my-app-abcde
409
+ baseUrl: "https://your-deployed-backend-url.com" // e.g., https://your-app-name.up.example.app
410
+ });
411
+
412
+ export default app;
413
+
414
+ ```
415
+
416
+ >🔗 The baseUrl should point to the backend URL you deployed earlier using Flowerbase.
417
+ This tells the frontend SDK where to send authentication and data requests.
418
+
419
+
420
+
@@ -63,7 +63,8 @@ export declare enum AUTH_ENDPOINTS {
63
63
  PROFILE = "/profile",
64
64
  SESSION = "/session",
65
65
  RESET = "/reset/call",
66
- CONFIRM_RESET = "/reset"
66
+ CONFIRM_RESET = "/reset",
67
+ FIRST_USER = "/setup/first-user"
67
68
  }
68
69
  export declare enum AUTH_ERRORS {
69
70
  INVALID_CREDENTIALS = "Invalid credentials",
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAGD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;CAUhC,CAAA;AAGD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAS/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,aAAa,WAAW;CACzB;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;CAC3D;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;CAChC;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,eAAO,MAAM,aAAa,mBAAmB,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAGjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAGrC,CAAA;AAID,eAAO,MAAM,aAAa,GAAI,qBAAqB,MAAM,EAAE,OAAO,MAAM,EAAE,SAAS,MAAM;;;;;CAyCxF,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAGD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;CAUhC,CAAA;AAGD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAS/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;CAC3D;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;CAChC;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,eAAO,MAAM,aAAa,mBAAmB,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAGjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAGrC,CAAA;AAID,eAAO,MAAM,aAAa,GAAI,qBAAqB,MAAM,EAAE,OAAO,MAAM,EAAE,SAAS,MAAM;;;;;CAyCxF,CAAA"}
@@ -55,6 +55,7 @@ var AUTH_ENDPOINTS;
55
55
  AUTH_ENDPOINTS["SESSION"] = "/session";
56
56
  AUTH_ENDPOINTS["RESET"] = "/reset/call";
57
57
  AUTH_ENDPOINTS["CONFIRM_RESET"] = "/reset";
58
+ AUTH_ENDPOINTS["FIRST_USER"] = "/setup/first-user";
58
59
  })(AUTH_ENDPOINTS || (exports.AUTH_ENDPOINTS = AUTH_ENDPOINTS = {}));
59
60
  var AUTH_ERRORS;
60
61
  (function (AUTH_ERRORS) {
@@ -1 +1 @@
1
- {"version":3,"file":"exposeRoutes.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/exposeRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAGzC;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAU,SAAS,eAAe,kBAgB1D,CAAA"}
1
+ {"version":3,"file":"exposeRoutes.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/exposeRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAMzC;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAU,SAAS,eAAe,kBAiE1D,CAAA"}
@@ -11,7 +11,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.exposeRoutes = void 0;
13
13
  const node_process_1 = require("node:process");
14
+ const utils_1 = require("../../auth/utils");
14
15
  const constants_1 = require("../../constants");
16
+ const crypto_1 = require("../crypto");
15
17
  /**
16
18
  * > Used to expose all app routes
17
19
  * @param fastify -> the fastify instance
@@ -33,6 +35,47 @@ const exposeRoutes = (fastify) => __awaiter(void 0, void 0, void 0, function* ()
33
35
  uptime: (0, node_process_1.uptime)()
34
36
  });
35
37
  }));
38
+ fastify.post(utils_1.AUTH_ENDPOINTS.FIRST_USER, {
39
+ schema: utils_1.REGISTRATION_SCHEMA
40
+ }, function (req, res) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ const { authCollection } = constants_1.AUTH_CONFIG;
43
+ const db = fastify.mongo.client.db(constants_1.DB_NAME);
44
+ const { email, password } = req.body;
45
+ const hashedPassword = yield (0, crypto_1.hashPassword)(password);
46
+ const users = db.collection(authCollection).find();
47
+ const list = yield (users === null || users === void 0 ? void 0 : users.toArray());
48
+ if (list === null || list === void 0 ? void 0 : list.length) {
49
+ res.status(409);
50
+ return {
51
+ error: `The ${authCollection} collection is not empty`
52
+ };
53
+ }
54
+ const result = yield db.collection(authCollection).insertOne({
55
+ email: email,
56
+ password: hashedPassword,
57
+ custom_data: {}
58
+ });
59
+ yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({
60
+ email: email
61
+ }, {
62
+ $set: {
63
+ identities: [
64
+ {
65
+ id: result === null || result === void 0 ? void 0 : result.insertedId.toString(),
66
+ provider_id: result === null || result === void 0 ? void 0 : result.insertedId.toString(),
67
+ provider_type: utils_1.PROVIDER_TYPE,
68
+ provider_data: { email }
69
+ }
70
+ ]
71
+ }
72
+ }));
73
+ res.status(201);
74
+ return {
75
+ userId: result === null || result === void 0 ? void 0 : result.insertedId
76
+ };
77
+ });
78
+ });
36
79
  }
37
80
  catch (e) {
38
81
  console.error('Error while exposing routes', e.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.0.1-beta.12",
3
+ "version": "1.0.1-beta.14",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/auth/utils.ts CHANGED
@@ -54,7 +54,8 @@ export enum AUTH_ENDPOINTS {
54
54
  PROFILE = '/profile',
55
55
  SESSION = '/session',
56
56
  RESET = '/reset/call',
57
- CONFIRM_RESET = "/reset"
57
+ CONFIRM_RESET = "/reset",
58
+ FIRST_USER = '/setup/first-user'
58
59
  }
59
60
 
60
61
  export enum AUTH_ERRORS {
@@ -1,6 +1,9 @@
1
1
  import { uptime } from 'node:process'
2
2
  import { FastifyInstance } from 'fastify'
3
- import { API_VERSION, DEFAULT_CONFIG } from '../../constants'
3
+ import { RegistrationDto } from '../../auth/providers/local-userpass/dtos'
4
+ import { AUTH_ENDPOINTS, PROVIDER_TYPE, REGISTRATION_SCHEMA } from '../../auth/utils'
5
+ import { API_VERSION, AUTH_CONFIG, DB_NAME, DEFAULT_CONFIG } from '../../constants'
6
+ import { hashPassword } from '../crypto'
4
7
 
5
8
  /**
6
9
  * > Used to expose all app routes
@@ -20,7 +23,58 @@ export const exposeRoutes = async (fastify: FastifyInstance) => {
20
23
  status: 'ok',
21
24
  uptime: uptime()
22
25
  }))
26
+
27
+ fastify.post<RegistrationDto>(AUTH_ENDPOINTS.FIRST_USER, {
28
+ schema: REGISTRATION_SCHEMA
29
+ }, async function (req, res) {
30
+ const { authCollection } = AUTH_CONFIG
31
+ const db = fastify.mongo.client.db(DB_NAME)
32
+ const { email, password } = req.body
33
+ const hashedPassword = await hashPassword(password)
34
+
35
+ const users = db.collection(authCollection!).find()
36
+
37
+ const list = await users?.toArray()
38
+
39
+ if (list?.length) {
40
+ res.status(409)
41
+ return {
42
+ error: `The ${authCollection} collection is not empty`
43
+ }
44
+ }
45
+
46
+ const result = await db.collection(authCollection!).insertOne({
47
+ email: email,
48
+ password: hashedPassword,
49
+ custom_data: {}
50
+ })
51
+
52
+ await db?.collection(authCollection!).updateOne(
53
+ {
54
+ email: email
55
+ },
56
+ {
57
+ $set: {
58
+ identities: [
59
+ {
60
+ id: result?.insertedId.toString(),
61
+ provider_id: result?.insertedId.toString(),
62
+ provider_type: PROVIDER_TYPE,
63
+ provider_data: { email }
64
+ }
65
+ ]
66
+ }
67
+ }
68
+ )
69
+
70
+ res.status(201)
71
+ return {
72
+ userId: result?.insertedId
73
+ }
74
+ })
23
75
  } catch (e) {
24
76
  console.error('Error while exposing routes', (e as Error).message)
25
77
  }
26
78
  }
79
+
80
+