Skip to content

Commit ebdd3a2

Browse files
committed
fix(api): allow all valid schema fields in profile updates and add social-demo app
1 parent cfddba7 commit ebdd3a2

52 files changed

Lines changed: 8199 additions & 15 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/public-api/src/controllers/userAuth.controller.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -343,16 +343,30 @@ module.exports.updateProfile = async (req, res) => {
343343
return res.status(401).json({ error: "Access Denied: Invalid or expired token" });
344344
}
345345

346-
const username = req.body.username;
347-
if (!username || username.length < 3 || username.length > 50) {
348-
return res.status(400).json({ error: "Username must be between 3 and 50 characters." });
346+
const updateData = { ...req.body };
347+
delete updateData.password;
348+
delete updateData.email;
349+
delete updateData._id;
350+
351+
if (updateData.username !== undefined) {
352+
const username = updateData.username;
353+
if (typeof username !== 'string' || username.length < 3 || username.length > 50) {
354+
return res.status(400).json({ error: "Username must be between 3 and 50 characters." });
355+
}
349356
}
350357

351-
const collection = await getAuthCollection(project);
358+
const sanitizedUpdateData = sanitize(updateData);
352359

353-
const result = await collection.updateOne(
360+
const usersColConfig = project.collections.find(c => c.name === 'users');
361+
if (!usersColConfig) return res.status(404).json({ error: "Auth collection not found" });
362+
363+
const connection = await getConnection(project._id);
364+
const Model = getCompiledModel(connection, usersColConfig, project._id, project.resources.db.isExternal);
365+
366+
const result = await Model.updateOne(
354367
{ _id: new mongoose.Types.ObjectId(decoded.userId) },
355-
{ $set: { username } }
368+
{ $set: sanitizedUpdateData },
369+
{ runValidators: true }
356370
);
357371

358372
res.json({ message: "Profile updated successfully" });

docs/authentication.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Creates a new user and returns a 7-day JWT token.
2121
**Endpoint**: `POST /api/userAuth/signup`
2222

2323
```javascript
24-
await fetch('https://api.urbackend.bitbros.in/api/userAuth/signup', {
24+
await fetch('https://api.ub.bitbros.in/api/userAuth/signup', {
2525
method: 'POST',
2626
headers: { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_KEY' },
2727
body: JSON.stringify({
@@ -40,7 +40,7 @@ Authenticates credentials and returns a 7-day JWT token.
4040
**Endpoint**: `POST /api/userAuth/login`
4141

4242
```javascript
43-
const res = await fetch('https://api.urbackend.bitbros.in/api/userAuth/login', {
43+
const res = await fetch('https://api.ub.bitbros.in/api/userAuth/login', {
4444
method: 'POST',
4545
headers: { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_KEY' },
4646
body: JSON.stringify({
@@ -58,7 +58,7 @@ Fetches the details of the currently authenticated user.
5858
**Endpoint**: `GET /api/userAuth/me`
5959

6060
```javascript
61-
await fetch('https://api.urbackend.bitbros.in/api/userAuth/me', {
61+
await fetch('https://api.ub.bitbros.in/api/userAuth/me', {
6262
headers: {
6363
'x-api-key': 'YOUR_KEY',
6464
'Authorization': `Bearer ${USER_TOKEN}`

docs/database.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ urBackend provides a simplified RESTful interface for MongoDB. There is no need
55
## Collection Access
66

77
All database endpoints follow the pattern:
8-
`https://api.urbackend.bitbros.in/api/data/:collectionName`
8+
`https://api.ub.bitbros.in/api/data/:collectionName`
99

1010
Replace `:collectionName` with the name of your collection (e.g., `posts`, `comments`, `inventory`).
1111

@@ -14,7 +14,7 @@ Replace `:collectionName` with the name of your collection (e.g., `posts`, `comm
1414
**Endpoint**: `POST /api/data/:collectionName`
1515

1616
```javascript
17-
await fetch('https://api.urbackend.bitbros.in/api/data/posts', {
17+
await fetch('https://api.ub.bitbros.in/api/data/posts', {
1818
method: 'POST',
1919
headers: { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_KEY' },
2020
body: JSON.stringify({
@@ -42,7 +42,7 @@ urBackend uses `$set` logic, meaning you only need to send the fields you want t
4242

4343
```javascript
4444
const postId = "YOUR_DOCUMENT_ID";
45-
await fetch(`https://api.urbackend.bitbros.in/api/data/posts/${postId}`, {
45+
await fetch(`https://api.ub.bitbros.in/api/data/posts/${postId}`, {
4646
method: 'PUT',
4747
headers: { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_KEY' },
4848
body: JSON.stringify({

docs/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ To get started, navigate to the **Database** tab in your dashboard and click **"
2424

2525
### Example: Storing a Product
2626
```javascript
27-
fetch('https://api.urbackend.bitbros.in/api/data/products', {
27+
fetch('https://api.ub.bitbros.in/api/data/products', {
2828
method: 'POST',
2929
headers: {
3030
'Content-Type': 'application/json',

docs/storage.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ To upload a file, send a `POST` request with a `multipart/form-data` body.
1212
const formData = new FormData();
1313
formData.append('file', fileInput.files[0]);
1414

15-
const res = await fetch('https://api.urbackend.bitbros.in/api/storage/upload', {
15+
const res = await fetch('https://api.ub.bitbros.in/api/storage/upload', {
1616
method: 'POST',
1717
headers: { 'x-api-key': 'YOUR_KEY' },
1818
body: formData
@@ -33,7 +33,7 @@ To delete a file, you must provide the `path` returned during the upload.
3333
**Endpoint**: `DELETE /api/storage/file`
3434

3535
```javascript
36-
await fetch('https://api.urbackend.bitbros.in/api/storage/file', {
36+
await fetch('https://api.ub.bitbros.in/api/storage/file', {
3737
method: 'DELETE',
3838
headers: { 'Content-Type': 'application/json', 'x-api-key': 'YOUR_KEY' },
3939
body: JSON.stringify({
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# 🎯 Quick Setup Guide - urBackend Collections
2+
3+
## Step-by-Step Collection Setup
4+
5+
### ⚠️ STEP 0: Enable Authentication (MUST DO FIRST!)
6+
7+
1. Login to urBackend Dashboard: https://urbackend.bitbros.in
8+
2. Go to your project
9+
3. Navigate to **Settings** or **Authentication** section
10+
4. **Enable Authentication** - Click the toggle/button
11+
5. This will automatically create a `users` collection with these fields:
12+
-`email` (String, Required, Unique)
13+
-`password` (String, Required, Auto-hashed with bcrypt)
14+
15+
---
16+
17+
### 📝 STEP 1: Update `users` Collection
18+
19+
After authentication is enabled, go to the `users` collection schema and **ADD** these fields:
20+
21+
```
22+
Field Name | Type | Required | Unique | Default
23+
------------------|---------|----------|--------|----------
24+
username | String | Yes | Yes | -
25+
displayName | String | No | No | -
26+
bio | String | No | No | -
27+
avatar | String | No | No | -
28+
banner | String | No | No | -
29+
verified | Boolean | No | No | false
30+
location | String | No | No | -
31+
website | String | No | No | -
32+
followersCount | Number | No | No | 0
33+
followingCount | Number | No | No | 0
34+
```
35+
36+
**Complete `users` schema will have:**
37+
- email ✅ (auto-created)
38+
- password ✅ (auto-created)
39+
- username + 9 additional fields (you add these)
40+
41+
---
42+
43+
### 📝 STEP 2: Create `posts` Collection
44+
45+
Create a new collection named **`posts`** with these fields:
46+
47+
```
48+
Field Name | Type | Required | Default
49+
--------------------|---------|----------|----------
50+
authorId | String | Yes | -
51+
authorUsername | String | Yes | -
52+
authorDisplayName | String | No | -
53+
authorAvatar | String | No | -
54+
authorVerified | Boolean | No | false
55+
content | String | Yes | -
56+
images | Array | No | []
57+
likesCount | Number | No | 0
58+
commentsCount | Number | No | 0
59+
retweetsCount | Number | No | 0
60+
createdAt | Date | No | Date.now
61+
```
62+
63+
---
64+
65+
### 📝 STEP 3: Create `comments` Collection
66+
67+
Create a new collection named **`comments`** with these fields:
68+
69+
```
70+
Field Name | Type | Required | Default
71+
--------------------|---------|----------|----------
72+
postId | String | Yes | -
73+
authorId | String | Yes | -
74+
authorUsername | String | Yes | -
75+
authorDisplayName | String | No | -
76+
authorAvatar | String | No | -
77+
content | String | Yes | -
78+
likesCount | Number | No | 0
79+
createdAt | Date | No | Date.now
80+
```
81+
82+
---
83+
84+
### 📝 STEP 4: Create `likes` Collection
85+
86+
Create a new collection named **`likes`** with these fields:
87+
88+
```
89+
Field Name | Type | Required | Index
90+
--------------|---------|----------|-------
91+
userId | String | Yes | Yes
92+
targetId | String | Yes | Yes
93+
targetType | String | Yes | No (enum: "post" or "comment")
94+
createdAt | Date | No | Date.now
95+
```
96+
97+
**Important:** Create a compound unique index on `userId + targetId` to prevent duplicate likes.
98+
99+
---
100+
101+
### 📝 STEP 5: Create `follows` Collection
102+
103+
Create a new collection named **`follows`** with these fields:
104+
105+
```
106+
Field Name | Type | Required | Index
107+
--------------|---------|----------|-------
108+
followerId | String | Yes | Yes
109+
followingId | String | Yes | Yes
110+
createdAt | Date | No | Date.now
111+
```
112+
113+
**Important:** Create a compound unique index on `followerId + followingId` to prevent duplicate follows.
114+
115+
---
116+
117+
## ✅ Verification Checklist
118+
119+
After completing all steps, verify:
120+
121+
- [ ] Authentication is enabled in urBackend dashboard
122+
- [ ] `users` collection exists with `email` and `password` fields
123+
- [ ] `users` collection has all 11 additional fields added
124+
- [ ] `posts` collection created with 11 fields
125+
- [ ] `comments` collection created with 8 fields
126+
- [ ] `likes` collection created with 4 fields
127+
- [ ] `follows` collection created with 3 fields
128+
- [ ] Total: 5 collections in your urBackend project
129+
130+
---
131+
132+
## 🔑 Get Your API Keys
133+
134+
1. Go to urBackend Dashboard → Project Settings
135+
2. Copy your **Public Key** (`pk_live_...`)
136+
3. Copy your **Secret Key** (`sk_live_...`)
137+
4. Paste them in your `.env` files (see main README.md)
138+
139+
---
140+
141+
## 🚀 Ready to Go!
142+
143+
Once all collections are created and API keys are configured, you can run the app:
144+
145+
```bash
146+
# Terminal 1
147+
cd server
148+
npm start
149+
150+
# Terminal 2
151+
cd client
152+
npm run dev
153+
```
154+
155+
Open http://localhost:5173 and create your first account! 🎉
156+
157+
---
158+
159+
## ❓ Common Issues
160+
161+
**Q: I don't see "Enable Authentication" option?**
162+
A: Look for "Auth Settings", "User Management", or check the main settings page. It might be under a different menu.
163+
164+
**Q: Can I use different field names?**
165+
A: No, the app code expects these exact field names. Changing them will break functionality.
166+
167+
**Q: What if I already created `users` collection manually?**
168+
A: Delete it and enable Authentication to let urBackend create it properly with password hashing.
169+
170+
**Q: Do I need to add indexes manually?**
171+
A: urBackend automatically indexes `_id`. For better performance, you can add indexes on frequently queried fields like `authorId`, `userId`, etc.
172+
173+
---
174+
175+
**Need help?** Check the full [SETUP.md](./SETUP.md) or join the Discord!

0 commit comments

Comments
 (0)