securepool 1.0.0
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/.dockerignore +7 -0
- package/.env.example +20 -0
- package/ARCHITECTURE.md +279 -0
- package/DEPLOYMENT.md +441 -0
- package/README.md +283 -0
- package/SETUP.md +388 -0
- package/apps/demo-backend/Dockerfile +33 -0
- package/apps/demo-backend/package.json +19 -0
- package/apps/demo-backend/src/index.ts +71 -0
- package/apps/demo-backend/tsconfig.json +8 -0
- package/apps/demo-frontend/.env.example +2 -0
- package/apps/demo-frontend/README.md +73 -0
- package/apps/demo-frontend/eslint.config.js +23 -0
- package/apps/demo-frontend/index.html +13 -0
- package/apps/demo-frontend/package.json +24 -0
- package/apps/demo-frontend/public/favicon.svg +1 -0
- package/apps/demo-frontend/public/icons.svg +24 -0
- package/apps/demo-frontend/src/App.tsx +33 -0
- package/apps/demo-frontend/src/assets/hero.png +0 -0
- package/apps/demo-frontend/src/assets/vite.svg +1 -0
- package/apps/demo-frontend/src/components/AccountSwitcher.tsx +373 -0
- package/apps/demo-frontend/src/components/ChangePasswordModal.tsx +128 -0
- package/apps/demo-frontend/src/index.css +272 -0
- package/apps/demo-frontend/src/main.tsx +10 -0
- package/apps/demo-frontend/src/pages/DashboardPage.tsx +141 -0
- package/apps/demo-frontend/src/pages/ForgotPasswordPage.tsx +183 -0
- package/apps/demo-frontend/src/pages/LoginPage.tsx +158 -0
- package/apps/demo-frontend/src/pages/OtpLoginPage.tsx +114 -0
- package/apps/demo-frontend/src/pages/SignupPage.tsx +95 -0
- package/apps/demo-frontend/src/pages/VerifyEmailPage.tsx +84 -0
- package/apps/demo-frontend/tsconfig.app.json +28 -0
- package/apps/demo-frontend/tsconfig.json +7 -0
- package/apps/demo-frontend/tsconfig.node.json +26 -0
- package/apps/demo-frontend/vite.config.ts +15 -0
- package/docs/DATABASE_MONGODB.md +280 -0
- package/docs/DATABASE_SQL.md +472 -0
- package/package.json +21 -0
- package/packages/api/package.json +30 -0
- package/packages/api/src/createSecurePool.ts +113 -0
- package/packages/api/src/index.ts +8 -0
- package/packages/api/src/middleware/authMiddleware.ts +26 -0
- package/packages/api/src/middleware/authorize.ts +24 -0
- package/packages/api/src/middleware/rateLimiter.ts +25 -0
- package/packages/api/src/middleware/tenantMiddleware.ts +12 -0
- package/packages/api/src/routes/authRoutes.ts +229 -0
- package/packages/api/src/routes/sessionRoutes.ts +30 -0
- package/packages/api/src/swagger.ts +529 -0
- package/packages/api/tsconfig.json +8 -0
- package/packages/application/package.json +16 -0
- package/packages/application/src/index.ts +17 -0
- package/packages/application/src/interfaces/IAuditLogRepository.ts +6 -0
- package/packages/application/src/interfaces/IAuthPlugin.ts +4 -0
- package/packages/application/src/interfaces/IEmailService.ts +3 -0
- package/packages/application/src/interfaces/IGoogleAuthService.ts +3 -0
- package/packages/application/src/interfaces/IOtpRepository.ts +8 -0
- package/packages/application/src/interfaces/IOtpService.ts +4 -0
- package/packages/application/src/interfaces/IPasswordHasher.ts +4 -0
- package/packages/application/src/interfaces/IRoleRepository.ts +8 -0
- package/packages/application/src/interfaces/ISessionRepository.ts +8 -0
- package/packages/application/src/interfaces/ITokenRepository.ts +9 -0
- package/packages/application/src/interfaces/ITokenService.ts +5 -0
- package/packages/application/src/interfaces/IUserRepository.ts +8 -0
- package/packages/application/src/services/AuthService.ts +323 -0
- package/packages/application/src/services/RefreshTokenService.ts +53 -0
- package/packages/application/tsconfig.json +8 -0
- package/packages/core/package.json +13 -0
- package/packages/core/src/entities/AuditLog.ts +11 -0
- package/packages/core/src/entities/OtpCode.ts +10 -0
- package/packages/core/src/entities/RefreshToken.ts +9 -0
- package/packages/core/src/entities/Role.ts +6 -0
- package/packages/core/src/entities/Session.ts +10 -0
- package/packages/core/src/entities/Tenant.ts +7 -0
- package/packages/core/src/entities/User.ts +10 -0
- package/packages/core/src/entities/UserRole.ts +6 -0
- package/packages/core/src/enums/index.ts +22 -0
- package/packages/core/src/index.ts +10 -0
- package/packages/core/tsconfig.json +8 -0
- package/packages/infrastructure/package.json +24 -0
- package/packages/infrastructure/src/email/NodemailerEmailService.ts +55 -0
- package/packages/infrastructure/src/google/GoogleAuthServiceImpl.ts +28 -0
- package/packages/infrastructure/src/hashing/BcryptHasher.ts +18 -0
- package/packages/infrastructure/src/index.ts +6 -0
- package/packages/infrastructure/src/jwt/JwtTokenService.ts +32 -0
- package/packages/infrastructure/src/otp/OtpServiceImpl.ts +50 -0
- package/packages/infrastructure/tsconfig.json +8 -0
- package/packages/persistence/package.json +22 -0
- package/packages/persistence/prisma/schema.prisma +88 -0
- package/packages/persistence/src/factory.ts +48 -0
- package/packages/persistence/src/index.ts +30 -0
- package/packages/persistence/src/mongo/connection.ts +9 -0
- package/packages/persistence/src/mongo/models/AuditLogModel.ts +21 -0
- package/packages/persistence/src/mongo/models/OtpModel.ts +19 -0
- package/packages/persistence/src/mongo/models/RefreshTokenModel.ts +17 -0
- package/packages/persistence/src/mongo/models/RoleModel.ts +11 -0
- package/packages/persistence/src/mongo/models/SessionModel.ts +19 -0
- package/packages/persistence/src/mongo/models/UserModel.ts +21 -0
- package/packages/persistence/src/mongo/models/UserRoleModel.ts +15 -0
- package/packages/persistence/src/mongo/repositories/MongoAuditLogRepository.ts +29 -0
- package/packages/persistence/src/mongo/repositories/MongoOtpRepository.ts +34 -0
- package/packages/persistence/src/mongo/repositories/MongoRoleRepository.ts +32 -0
- package/packages/persistence/src/mongo/repositories/MongoSessionRepository.ts +29 -0
- package/packages/persistence/src/mongo/repositories/MongoTokenRepository.ts +34 -0
- package/packages/persistence/src/mongo/repositories/MongoUserRepository.ts +37 -0
- package/packages/persistence/src/prisma/repositories/PrismaAuditLogRepository.ts +37 -0
- package/packages/persistence/src/prisma/repositories/PrismaOtpRepository.ts +43 -0
- package/packages/persistence/src/prisma/repositories/PrismaRoleRepository.ts +36 -0
- package/packages/persistence/src/prisma/repositories/PrismaSessionRepository.ts +39 -0
- package/packages/persistence/src/prisma/repositories/PrismaTokenRepository.ts +50 -0
- package/packages/persistence/src/prisma/repositories/PrismaUserRepository.ts +45 -0
- package/packages/persistence/tsconfig.json +8 -0
- package/packages/react-sdk/package.json +23 -0
- package/packages/react-sdk/src/components/GoogleLoginButton.tsx +54 -0
- package/packages/react-sdk/src/components/LoginForm.tsx +67 -0
- package/packages/react-sdk/src/components/OTPVerification.tsx +104 -0
- package/packages/react-sdk/src/components/SessionList.tsx +64 -0
- package/packages/react-sdk/src/components/SignupForm.tsx +95 -0
- package/packages/react-sdk/src/context/AuthContext.ts +4 -0
- package/packages/react-sdk/src/context/SecurePoolProvider.tsx +492 -0
- package/packages/react-sdk/src/hooks/useAuth.ts +11 -0
- package/packages/react-sdk/src/index.ts +22 -0
- package/packages/react-sdk/src/types.ts +53 -0
- package/packages/react-sdk/tsconfig.json +12 -0
- package/scripts/setup.js +285 -0
- package/scripts/setup.sh +309 -0
- package/tsconfig.base.json +16 -0
- package/turbo.json +16 -0
package/DEPLOYMENT.md
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
# SecurePool - Deployment Guide
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
|
|
7
|
+
│ Frontend │────▶│ Backend API │────▶│ MongoDB │
|
|
8
|
+
│ (Vercel) │ │ (Railway/Render) │ │ (Atlas) │
|
|
9
|
+
│ Static files │ │ Node.js server │ │ Cloud DB │
|
|
10
|
+
└─────────────────┘ └──────────────────┘ └─────────────┘
|
|
11
|
+
apps/demo-frontend apps/demo-backend MongoDB Atlas
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Deployment Targets
|
|
15
|
+
|
|
16
|
+
| What | Platform | Why |
|
|
17
|
+
|------|----------|-----|
|
|
18
|
+
| Database | MongoDB Atlas | Free cloud DB, no server to manage |
|
|
19
|
+
| Backend API | Railway / Render | Node.js hosting, auto-deploys from GitHub |
|
|
20
|
+
| Frontend | Vercel / Netlify | Free static hosting, auto-deploys from GitHub |
|
|
21
|
+
| NPM Packages | npmjs.com | So other devs can install your library |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Prerequisites
|
|
26
|
+
|
|
27
|
+
Before deploying, make sure:
|
|
28
|
+
|
|
29
|
+
- [ ] Your code is pushed to a **GitHub repository**
|
|
30
|
+
- [ ] You have accounts on [MongoDB Atlas](https://cloud.mongodb.com), [Railway](https://railway.app), and [Vercel](https://vercel.com)
|
|
31
|
+
- [ ] Your project builds locally (`npm run build` succeeds)
|
|
32
|
+
- [ ] Your `.pem` files are ready (you'll convert them to env vars)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Step 1: MongoDB Atlas (Cloud Database)
|
|
37
|
+
|
|
38
|
+
### 1.1 Create Cluster
|
|
39
|
+
|
|
40
|
+
1. Go to https://cloud.mongodb.com
|
|
41
|
+
2. Click **"Build a Database"**
|
|
42
|
+
3. Choose **M0 Free Tier**
|
|
43
|
+
4. Select region closest to your backend (e.g., AWS Mumbai for India)
|
|
44
|
+
5. Click **Create**
|
|
45
|
+
|
|
46
|
+
### 1.2 Create Database User
|
|
47
|
+
|
|
48
|
+
1. Go to **Database Access** (left sidebar)
|
|
49
|
+
2. Click **"Add New Database User"**
|
|
50
|
+
3. Set:
|
|
51
|
+
- Username: `securepool-user`
|
|
52
|
+
- Password: `SecurePool@123`
|
|
53
|
+
- Role: **Read and write to any database**
|
|
54
|
+
4. Click **Add User**
|
|
55
|
+
|
|
56
|
+
### 1.3 Allow Network Access
|
|
57
|
+
|
|
58
|
+
1. Go to **Network Access** (left sidebar)
|
|
59
|
+
2. Click **"Add IP Address"**
|
|
60
|
+
3. Click **"Allow Access from Anywhere"** (`0.0.0.0/0`)
|
|
61
|
+
4. Click **Confirm**
|
|
62
|
+
|
|
63
|
+
> For production, restrict to your backend server's IP only.
|
|
64
|
+
|
|
65
|
+
### 1.4 Get Connection String
|
|
66
|
+
|
|
67
|
+
1. Go to **Database** (left sidebar)
|
|
68
|
+
2. Click **"Connect"** on your cluster
|
|
69
|
+
3. Choose **"Drivers"**
|
|
70
|
+
4. Copy the connection string:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
mongodb+srv://securepool-user:SecurePool%40123@cluster0.xxxxx.mongodb.net/securepool
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
> Replace `cluster0.xxxxx` with your actual cluster address.
|
|
77
|
+
> The `@` in password is encoded as `%40`.
|
|
78
|
+
|
|
79
|
+
### 1.5 Verify Connection
|
|
80
|
+
|
|
81
|
+
Test from your terminal:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
mongosh "mongodb+srv://securepool-user:SecurePool%40123@cluster0.xxxxx.mongodb.net/securepool"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
If it connects, your database is ready.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Step 2: Prepare JWT Keys for Production
|
|
92
|
+
|
|
93
|
+
Locally, you use `.pem` files. In production, you pass the key content as environment variables.
|
|
94
|
+
|
|
95
|
+
### Convert .pem files to single-line format
|
|
96
|
+
|
|
97
|
+
Run these in your `securepool/` directory:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Private key (copy the entire output)
|
|
101
|
+
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' private.pem
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Public key (copy the entire output)
|
|
106
|
+
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' public.pem
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Each command outputs a single line like:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA...\n-----END RSA PRIVATE KEY-----\n
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Save both outputs** — you'll paste them as env vars in Railway.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Step 3: Deploy Backend on Railway
|
|
120
|
+
|
|
121
|
+
### 3.1 Create Project
|
|
122
|
+
|
|
123
|
+
1. Go to https://railway.app
|
|
124
|
+
2. Click **"New Project"**
|
|
125
|
+
3. Choose **"Deploy from GitHub Repo"**
|
|
126
|
+
4. Select your repository
|
|
127
|
+
5. Railway auto-detects Node.js
|
|
128
|
+
|
|
129
|
+
### 3.2 Configure Build & Start
|
|
130
|
+
|
|
131
|
+
Go to your service → **Settings** tab:
|
|
132
|
+
|
|
133
|
+
| Setting | Value |
|
|
134
|
+
|---------|-------|
|
|
135
|
+
| Root Directory | `/` (leave empty, monorepo root) |
|
|
136
|
+
| Build Command | `npm ci && npx turbo run build --filter=@securepool/* && cd apps/demo-backend && npx tsc` |
|
|
137
|
+
| Start Command | `node apps/demo-backend/dist/index.js` |
|
|
138
|
+
|
|
139
|
+
### 3.3 Add Environment Variables
|
|
140
|
+
|
|
141
|
+
Go to **Variables** tab and add each:
|
|
142
|
+
|
|
143
|
+
```env
|
|
144
|
+
# Database
|
|
145
|
+
DB_TYPE=mongo
|
|
146
|
+
DB_URL=mongodb+srv://securepool-user:SecurePool%40123@cluster0.xxxxx.mongodb.net/securepool
|
|
147
|
+
|
|
148
|
+
# JWT (paste the single-line output from Step 2)
|
|
149
|
+
JWT_PRIVATE_KEY=-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAK...\n-----END RSA PRIVATE KEY-----\n
|
|
150
|
+
JWT_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----\nMIIBIjANBgk...\n-----END PUBLIC KEY-----\n
|
|
151
|
+
|
|
152
|
+
# Email
|
|
153
|
+
EMAIL_HOST=smtp.gmail.com
|
|
154
|
+
EMAIL_PORT=587
|
|
155
|
+
EMAIL_SECURE=false
|
|
156
|
+
EMAIL_USER=demandon.ps@gmail.com
|
|
157
|
+
EMAIL_PASS=hjggfnfiskzzrnuy
|
|
158
|
+
EMAIL_FROM=demandon.ps@gmail.com
|
|
159
|
+
|
|
160
|
+
# Server
|
|
161
|
+
PORT=5001
|
|
162
|
+
CORS_ORIGINS=*
|
|
163
|
+
RATE_LIMIT_ENABLED=true
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
> Set `CORS_ORIGINS=*` for now. Update it after getting your Vercel frontend URL.
|
|
167
|
+
|
|
168
|
+
### 3.4 Deploy
|
|
169
|
+
|
|
170
|
+
Click **"Deploy"**. Railway builds and starts your server.
|
|
171
|
+
|
|
172
|
+
### 3.5 Get Your Backend URL
|
|
173
|
+
|
|
174
|
+
After deployment, Railway gives you a URL:
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
https://securepool-production.up.railway.app
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 3.6 Verify
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
curl https://securepool-production.up.railway.app/health
|
|
184
|
+
# → {"status":"ok"}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Check Swagger docs:
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
https://securepool-production.up.railway.app/docs
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Step 4: Deploy Frontend on Vercel
|
|
196
|
+
|
|
197
|
+
### 4.1 Create Project
|
|
198
|
+
|
|
199
|
+
1. Go to https://vercel.com
|
|
200
|
+
2. Click **"Add New Project"**
|
|
201
|
+
3. **Import** your GitHub repository
|
|
202
|
+
|
|
203
|
+
### 4.2 Configure Build
|
|
204
|
+
|
|
205
|
+
| Setting | Value |
|
|
206
|
+
|---------|-------|
|
|
207
|
+
| Framework Preset | Vite |
|
|
208
|
+
| Root Directory | `apps/demo-frontend` |
|
|
209
|
+
| Build Command | `cd ../.. && npm ci && npx turbo run build --filter=@securepool/react-sdk && cd apps/demo-frontend && npx vite build` |
|
|
210
|
+
| Output Directory | `dist` |
|
|
211
|
+
|
|
212
|
+
### 4.3 Add Environment Variable
|
|
213
|
+
|
|
214
|
+
```env
|
|
215
|
+
VITE_API_URL=https://securepool-production.up.railway.app
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 4.4 Deploy
|
|
219
|
+
|
|
220
|
+
Click **"Deploy"**. Vercel builds the static React app.
|
|
221
|
+
|
|
222
|
+
### 4.5 Get Your Frontend URL
|
|
223
|
+
|
|
224
|
+
Vercel gives you:
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
https://securepool.vercel.app
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### 4.6 Update CORS on Railway
|
|
231
|
+
|
|
232
|
+
Go back to Railway → **Variables** → Update:
|
|
233
|
+
|
|
234
|
+
```env
|
|
235
|
+
CORS_ORIGINS=https://securepool.vercel.app
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Railway auto-redeploys with the new CORS setting.
|
|
239
|
+
|
|
240
|
+
### 4.7 Verify
|
|
241
|
+
|
|
242
|
+
Open `https://securepool.vercel.app` — you should see the login page. Register a new account, check your email for OTP, and login.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Step 5: Publish NPM Packages (Optional)
|
|
247
|
+
|
|
248
|
+
This lets other developers install your library with `npm install @securepool/api`.
|
|
249
|
+
|
|
250
|
+
### 5.1 Create npm Account
|
|
251
|
+
|
|
252
|
+
1. Go to https://www.npmjs.com/signup
|
|
253
|
+
2. Create an account
|
|
254
|
+
|
|
255
|
+
### 5.2 Login from Terminal
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
npm login
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### 5.3 Create npm Organization (for scoped packages)
|
|
262
|
+
|
|
263
|
+
1. Go to https://www.npmjs.com/org/create
|
|
264
|
+
2. Create organization named `securepool`
|
|
265
|
+
3. This reserves the `@securepool/` scope
|
|
266
|
+
|
|
267
|
+
### 5.4 Publish All Packages
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
cd securepool
|
|
271
|
+
|
|
272
|
+
# Publish in dependency order
|
|
273
|
+
cd packages/core && npm publish --access public && cd ../..
|
|
274
|
+
cd packages/application && npm publish --access public && cd ../..
|
|
275
|
+
cd packages/infrastructure && npm publish --access public && cd ../..
|
|
276
|
+
cd packages/persistence && npm publish --access public && cd ../..
|
|
277
|
+
cd packages/api && npm publish --access public && cd ../..
|
|
278
|
+
cd packages/react-sdk && npm publish --access public && cd ../..
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 5.5 Verify
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
npm info @securepool/api
|
|
285
|
+
npm info @securepool/react-sdk
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 5.6 How Others Use It
|
|
289
|
+
|
|
290
|
+
**Their backend:**
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
npm install @securepool/api
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
import { createSecurePool } from "@securepool/api";
|
|
298
|
+
|
|
299
|
+
const { app } = await createSecurePool({
|
|
300
|
+
database: { type: "mongo", url: process.env.DB_URL },
|
|
301
|
+
jwt: { privateKey: "...", publicKey: "..." },
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
app.listen(3000);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Their frontend:**
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
npm install @securepool/react-sdk
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
import { SecurePoolProvider, LoginForm } from "@securepool/react-sdk";
|
|
315
|
+
|
|
316
|
+
<SecurePoolProvider config={{ apiBaseUrl: "https://api.example.com", tenantId: "default" }}>
|
|
317
|
+
<LoginForm />
|
|
318
|
+
</SecurePoolProvider>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Alternative: Deploy with Docker
|
|
324
|
+
|
|
325
|
+
If you prefer Docker (for AWS ECS, DigitalOcean, etc.):
|
|
326
|
+
|
|
327
|
+
### Build
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
cd securepool
|
|
331
|
+
docker build -f apps/demo-backend/Dockerfile -t securepool-api .
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Run
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
docker run -p 5001:5001 \
|
|
338
|
+
-e DB_TYPE=mongo \
|
|
339
|
+
-e DB_URL="mongodb+srv://..." \
|
|
340
|
+
-e JWT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n..." \
|
|
341
|
+
-e JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n..." \
|
|
342
|
+
-e EMAIL_HOST=smtp.gmail.com \
|
|
343
|
+
-e EMAIL_PORT=587 \
|
|
344
|
+
-e EMAIL_SECURE=false \
|
|
345
|
+
-e EMAIL_USER=demandon.ps@gmail.com \
|
|
346
|
+
-e EMAIL_PASS=hjggfnfiskzzrnuy \
|
|
347
|
+
-e EMAIL_FROM=demandon.ps@gmail.com \
|
|
348
|
+
-e PORT=5001 \
|
|
349
|
+
-e CORS_ORIGINS="*" \
|
|
350
|
+
-e RATE_LIMIT_ENABLED=true \
|
|
351
|
+
securepool-api
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Push to Docker Hub
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
docker tag securepool-api yourusername/securepool-api:latest
|
|
358
|
+
docker push yourusername/securepool-api:latest
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Post-Deployment Checklist
|
|
364
|
+
|
|
365
|
+
After deploying, verify everything works:
|
|
366
|
+
|
|
367
|
+
- [ ] `GET /health` returns `{"status":"ok"}`
|
|
368
|
+
- [ ] `GET /docs` shows Swagger UI
|
|
369
|
+
- [ ] Register a new user (OTP email received)
|
|
370
|
+
- [ ] Verify email with OTP
|
|
371
|
+
- [ ] Login with email/password
|
|
372
|
+
- [ ] Login with OTP
|
|
373
|
+
- [ ] Forgot password flow works
|
|
374
|
+
- [ ] Change password from dashboard
|
|
375
|
+
- [ ] Sessions show up in dashboard
|
|
376
|
+
- [ ] Multi-account switching works
|
|
377
|
+
- [ ] `CORS_ORIGINS` is set to your Vercel URL (not `*`)
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## Environment Variables Reference
|
|
382
|
+
|
|
383
|
+
### Backend (Railway)
|
|
384
|
+
|
|
385
|
+
| Variable | Required | Example | Description |
|
|
386
|
+
|----------|----------|---------|-------------|
|
|
387
|
+
| `DB_TYPE` | Yes | `mongo` | Database type: `mongo` or `postgres` |
|
|
388
|
+
| `DB_URL` | Yes | `mongodb+srv://...` | Database connection string |
|
|
389
|
+
| `JWT_PRIVATE_KEY` | Yes | `-----BEGIN RSA...` | RSA private key (single line, `\n` for newlines) |
|
|
390
|
+
| `JWT_PUBLIC_KEY` | Yes | `-----BEGIN PUBLIC...` | RSA public key (single line, `\n` for newlines) |
|
|
391
|
+
| `EMAIL_HOST` | No | `smtp.gmail.com` | SMTP host |
|
|
392
|
+
| `EMAIL_PORT` | No | `587` | SMTP port |
|
|
393
|
+
| `EMAIL_SECURE` | No | `false` | Use TLS (`true` for port 465) |
|
|
394
|
+
| `EMAIL_USER` | No | `you@gmail.com` | SMTP username |
|
|
395
|
+
| `EMAIL_PASS` | No | `abcdefghijklmnop` | Gmail App Password |
|
|
396
|
+
| `EMAIL_FROM` | No | `you@gmail.com` | Sender email address |
|
|
397
|
+
| `PORT` | No | `5001` | Server port (Railway sets this automatically) |
|
|
398
|
+
| `CORS_ORIGINS` | Yes | `https://app.vercel.app` | Allowed frontend origin |
|
|
399
|
+
| `RATE_LIMIT_ENABLED` | No | `true` | Enable rate limiting |
|
|
400
|
+
|
|
401
|
+
### Frontend (Vercel)
|
|
402
|
+
|
|
403
|
+
| Variable | Required | Example | Description |
|
|
404
|
+
|----------|----------|---------|-------------|
|
|
405
|
+
| `VITE_API_URL` | Yes | `https://api.railway.app` | Backend API URL |
|
|
406
|
+
| `VITE_TENANT_ID` | No | `default` | Default tenant ID |
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Updating After Deployment
|
|
411
|
+
|
|
412
|
+
### Push code changes
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
git add .
|
|
416
|
+
git commit -m "your changes"
|
|
417
|
+
git push
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Railway and Vercel auto-redeploy on push.
|
|
421
|
+
|
|
422
|
+
### Update npm packages
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
# Bump version in each package.json, then:
|
|
426
|
+
cd packages/core && npm publish --access public
|
|
427
|
+
# ... repeat for changed packages
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## Cost Summary
|
|
433
|
+
|
|
434
|
+
| Service | Free Tier | Paid |
|
|
435
|
+
|---------|-----------|------|
|
|
436
|
+
| MongoDB Atlas | 512MB storage, shared cluster | $9/mo for dedicated |
|
|
437
|
+
| Railway | 500 hours/month, 8GB RAM | $5/mo for always-on |
|
|
438
|
+
| Vercel | Unlimited static sites | $20/mo for team features |
|
|
439
|
+
| npm | Unlimited public packages | Free |
|
|
440
|
+
|
|
441
|
+
**Total for hobby/MVP: $0/month**
|
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# SecurePool
|
|
2
|
+
|
|
3
|
+
Production-grade, self-hosted authentication framework for Node.js and React. Plug-and-play JWT auth, OTP, Google SSO, multi-tenancy, session management — distributed as NPM packages.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Run Locally (3 Commands)
|
|
8
|
+
|
|
9
|
+
### Prerequisites
|
|
10
|
+
|
|
11
|
+
| Tool | Required | Install |
|
|
12
|
+
|------|----------|---------|
|
|
13
|
+
| **Node.js 20+** | Yes | [nodejs.org](https://nodejs.org) |
|
|
14
|
+
| **MongoDB 6+** | Yes | See below |
|
|
15
|
+
| **Git** | Yes | Pre-installed on Mac. Windows: [git-scm.com](https://git-scm.com) |
|
|
16
|
+
|
|
17
|
+
### Install MongoDB
|
|
18
|
+
|
|
19
|
+
**macOS:**
|
|
20
|
+
```bash
|
|
21
|
+
brew tap mongodb/brew
|
|
22
|
+
brew install mongodb-community
|
|
23
|
+
brew services start mongodb-community
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Windows:**
|
|
27
|
+
1. Download from https://www.mongodb.com/try/download/community
|
|
28
|
+
2. Run the installer (choose "Complete" install)
|
|
29
|
+
3. Check "Install MongoDB as a Service"
|
|
30
|
+
4. Also install [mongosh](https://www.mongodb.com/try/download/shell)
|
|
31
|
+
|
|
32
|
+
**Linux (Ubuntu/Debian):**
|
|
33
|
+
```bash
|
|
34
|
+
sudo apt-get install -y mongodb-org
|
|
35
|
+
sudo systemctl start mongod
|
|
36
|
+
sudo systemctl enable mongod
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Setup & Run
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Step 1: Clone and enter the project
|
|
43
|
+
git clone <your-repo-url>
|
|
44
|
+
cd securepool
|
|
45
|
+
|
|
46
|
+
# Step 2: Run interactive setup (installs deps, generates keys, configures DB & email, builds)
|
|
47
|
+
npm run setup
|
|
48
|
+
|
|
49
|
+
# Step 3: Start both servers
|
|
50
|
+
npm run start:backend # Terminal 1 → API on http://localhost:5001
|
|
51
|
+
npm run start:frontend # Terminal 2 → UI on http://localhost:5173
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
That's it. Open http://localhost:5173 and register your first account.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Database Support
|
|
59
|
+
|
|
60
|
+
SecurePool supports **MongoDB** and **SQL databases** (PostgreSQL / MySQL). Switch with one config change:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// MongoDB
|
|
64
|
+
createSecurePool({ database: { type: "mongo", url: "mongodb://..." } })
|
|
65
|
+
|
|
66
|
+
// PostgreSQL
|
|
67
|
+
createSecurePool({ database: { type: "postgres", url: "postgresql://..." } })
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Database | Guide | ORM | Migration needed? |
|
|
71
|
+
|----------|-------|-----|-------------------|
|
|
72
|
+
| MongoDB | [DATABASE_MONGODB.md](docs/DATABASE_MONGODB.md) | Mongoose | No (auto-creates collections) |
|
|
73
|
+
| PostgreSQL | [DATABASE_SQL.md](docs/DATABASE_SQL.md) | Prisma | Yes (`prisma migrate dev`) |
|
|
74
|
+
| MySQL | [DATABASE_SQL.md](docs/DATABASE_SQL.md) | Prisma | Yes (`prisma migrate dev`) |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Documentation
|
|
79
|
+
|
|
80
|
+
| Document | What it covers |
|
|
81
|
+
|----------|---------------|
|
|
82
|
+
| [SETUP.md](SETUP.md) | Local development — prerequisites, RSA keys, `.env`, running backend + frontend |
|
|
83
|
+
| [ARCHITECTURE.md](ARCHITECTURE.md) | Why monorepo, packages vs apps, dependency flow, clean architecture layers |
|
|
84
|
+
| [DEPLOYMENT.md](DEPLOYMENT.md) | Production — cloud DB, Railway (backend), Vercel (frontend), npm publishing, Docker |
|
|
85
|
+
| [DATABASE_MONGODB.md](docs/DATABASE_MONGODB.md) | MongoDB — local setup, Atlas cloud, collections, indexes, monitoring |
|
|
86
|
+
| [DATABASE_SQL.md](docs/DATABASE_SQL.md) | PostgreSQL / MySQL — local setup, cloud providers, Prisma migrations, schema details |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### What `npm run setup` Does
|
|
91
|
+
|
|
92
|
+
The setup script runs on **Mac, Windows, and Linux** (it's a Node.js script, not bash). It will:
|
|
93
|
+
|
|
94
|
+
1. Check prerequisites (Node.js, MongoDB, OpenSSL)
|
|
95
|
+
2. Run `npm install`
|
|
96
|
+
3. Generate RSA keys for JWT (`private.pem`, `public.pem`)
|
|
97
|
+
4. Ask you to choose database mode (simple / with auth / custom URL)
|
|
98
|
+
5. Optionally configure Gmail SMTP for OTP emails
|
|
99
|
+
6. Create your `.env` file
|
|
100
|
+
7. Build all 6 packages
|
|
101
|
+
|
|
102
|
+
### URLs After Setup
|
|
103
|
+
|
|
104
|
+
| URL | What |
|
|
105
|
+
|-----|------|
|
|
106
|
+
| http://localhost:5173 | Frontend — login, signup, dashboard |
|
|
107
|
+
| http://localhost:5001/docs | Swagger API Docs — try all endpoints live |
|
|
108
|
+
| http://localhost:5001/health | Health check |
|
|
109
|
+
|
|
110
|
+
### Killing a Running Server
|
|
111
|
+
|
|
112
|
+
If you get `EADDRINUSE` (port already in use):
|
|
113
|
+
|
|
114
|
+
**macOS / Linux:**
|
|
115
|
+
```bash
|
|
116
|
+
lsof -ti:5001 | xargs kill -9
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Windows (PowerShell):**
|
|
120
|
+
```powershell
|
|
121
|
+
Get-Process -Id (Get-NetTCPConnection -LocalPort 5001).OwningProcess | Stop-Process -Force
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Features
|
|
127
|
+
|
|
128
|
+
- **JWT Authentication** — RS256-based access + refresh tokens with rotation
|
|
129
|
+
- **OTP Login** — Email-based one-time passwords with expiry and attempt limits
|
|
130
|
+
- **Email Verification** — OTP-verified registration (user created only after verification)
|
|
131
|
+
- **Password Management** — Forgot password (OTP reset) + change password (authenticated)
|
|
132
|
+
- **Google SSO** — Login with Google ID tokens
|
|
133
|
+
- **Multi-Tenancy** — Tenant-isolated data via `x-tenant-id` header
|
|
134
|
+
- **Session Management** — Device tracking, session listing, per-device revocation
|
|
135
|
+
- **Multi-Account Switching** — Store multiple accounts, switch without re-login
|
|
136
|
+
- **Role-Based Access Control** — RBAC middleware for route protection
|
|
137
|
+
- **Multi-Database** — MongoDB (Mongoose) and PostgreSQL (Prisma) out of the box
|
|
138
|
+
- **Rate Limiting** — Per-route rate limits (login, OTP, general)
|
|
139
|
+
- **Audit Logging** — Tracks login, register, password reset, OTP events
|
|
140
|
+
- **Swagger API Docs** — Interactive API explorer at `/docs`
|
|
141
|
+
- **React SDK** — Provider, hooks, pre-built components (LoginForm, SignupForm, OTP, SessionList)
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Install as NPM Package
|
|
146
|
+
|
|
147
|
+
**Backend:**
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npm install @securepool/api
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import { createSecurePool } from "@securepool/api";
|
|
155
|
+
|
|
156
|
+
const { app } = await createSecurePool({
|
|
157
|
+
database: { type: "mongo", url: "mongodb://localhost:27017/myapp" },
|
|
158
|
+
jwt: { privateKey: "...", publicKey: "..." },
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
app.listen(3000);
|
|
162
|
+
// Auth endpoints ready: /auth/login, /auth/register, /sessions, etc.
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Frontend:**
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
npm install @securepool/react-sdk
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { SecurePoolProvider, LoginForm, useAuth } from "@securepool/react-sdk";
|
|
173
|
+
|
|
174
|
+
function App() {
|
|
175
|
+
return (
|
|
176
|
+
<SecurePoolProvider config={{ apiBaseUrl: "http://localhost:3000", tenantId: "default" }}>
|
|
177
|
+
<LoginForm onSuccess={() => console.log("Logged in!")} />
|
|
178
|
+
</SecurePoolProvider>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Packages
|
|
186
|
+
|
|
187
|
+
| Package | Description |
|
|
188
|
+
|---------|-------------|
|
|
189
|
+
| `@securepool/core` | Entities and enums (User, Role, Session, OTP, etc.) |
|
|
190
|
+
| `@securepool/application` | Business logic, interfaces, AuthService |
|
|
191
|
+
| `@securepool/infrastructure` | JWT, bcrypt, OTP, Nodemailer, Google SSO |
|
|
192
|
+
| `@securepool/persistence` | MongoDB + PostgreSQL repository implementations |
|
|
193
|
+
| `@securepool/api` | Express routes, middleware, `createSecurePool()` |
|
|
194
|
+
| `@securepool/react-sdk` | React provider, `useAuth()` hook, UI components |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## API Endpoints
|
|
199
|
+
|
|
200
|
+
| Method | Endpoint | Auth | Description |
|
|
201
|
+
|--------|----------|------|-------------|
|
|
202
|
+
| GET | `/health` | No | Health check |
|
|
203
|
+
| GET | `/docs` | No | Swagger API documentation |
|
|
204
|
+
| POST | `/auth/register` | No | Register + send verification OTP |
|
|
205
|
+
| POST | `/auth/verify-email` | No | Verify OTP and create account |
|
|
206
|
+
| POST | `/auth/login` | No | Login with email + password |
|
|
207
|
+
| POST | `/auth/otp/request` | No | Request OTP for login |
|
|
208
|
+
| POST | `/auth/otp/verify` | No | Verify OTP and login |
|
|
209
|
+
| POST | `/auth/google` | No | Google SSO login |
|
|
210
|
+
| POST | `/auth/refresh` | No | Refresh access token |
|
|
211
|
+
| POST | `/auth/forgot-password` | No | Send password reset OTP |
|
|
212
|
+
| POST | `/auth/reset-password` | No | Reset password with OTP |
|
|
213
|
+
| POST | `/auth/change-password` | Yes | Change password (old + new) |
|
|
214
|
+
| GET | `/sessions` | Yes | List active sessions |
|
|
215
|
+
| DELETE | `/sessions/:id` | Yes | Revoke a session |
|
|
216
|
+
| DELETE | `/sessions` | Yes | Revoke all sessions |
|
|
217
|
+
|
|
218
|
+
All `/auth/*` routes require `x-tenant-id` header. Authenticated routes require `Authorization: Bearer <token>`.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Project Structure
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
securepool/
|
|
226
|
+
├── packages/ # NPM library packages (the product)
|
|
227
|
+
│ ├── core/ # Entities, enums — zero dependencies
|
|
228
|
+
│ ├── application/ # Interfaces, AuthService — business logic
|
|
229
|
+
│ ├── infrastructure/ # JWT, bcrypt, OTP, email — implementations
|
|
230
|
+
│ ├── persistence/ # MongoDB + PostgreSQL — database layer
|
|
231
|
+
│ ├── api/ # Express server — routes, middleware, Swagger
|
|
232
|
+
│ └── react-sdk/ # React — provider, hooks, UI components
|
|
233
|
+
│
|
|
234
|
+
├── apps/ # Demo applications (for testing)
|
|
235
|
+
│ ├── demo-backend/ # Example server using @securepool/api
|
|
236
|
+
│ └── demo-frontend/ # Example React app using @securepool/react-sdk
|
|
237
|
+
│
|
|
238
|
+
├── scripts/
|
|
239
|
+
│ └── setup.sh # One-command setup script
|
|
240
|
+
│
|
|
241
|
+
├── docs/
|
|
242
|
+
│ ├── DATABASE_MONGODB.md # MongoDB setup (local + Atlas)
|
|
243
|
+
│ └── DATABASE_SQL.md # PostgreSQL / MySQL setup (local + cloud)
|
|
244
|
+
│
|
|
245
|
+
├── SETUP.md # Local development guide
|
|
246
|
+
├── ARCHITECTURE.md # Code structure and design decisions
|
|
247
|
+
├── DEPLOYMENT.md # Production deployment guide
|
|
248
|
+
└── README.md # This file
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Commands
|
|
254
|
+
|
|
255
|
+
| Command | Description |
|
|
256
|
+
|---------|-------------|
|
|
257
|
+
| `npm run setup` | Interactive first-time setup (DB, keys, email, build) |
|
|
258
|
+
| `npm run build` | Build all packages |
|
|
259
|
+
| `npm run start:backend` | Start API server on port 5001 |
|
|
260
|
+
| `npm run start:frontend` | Start React app on port 5173 |
|
|
261
|
+
| `npm run clean` | Delete all dist folders |
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Tech Stack
|
|
266
|
+
|
|
267
|
+
| Layer | Technology |
|
|
268
|
+
|-------|-----------|
|
|
269
|
+
| Runtime | Node.js 20+ |
|
|
270
|
+
| Language | TypeScript (strict mode) |
|
|
271
|
+
| Backend Framework | Express.js |
|
|
272
|
+
| Database | MongoDB (Mongoose) / PostgreSQL (Prisma) |
|
|
273
|
+
| Authentication | JWT (RS256), bcrypt, OTP |
|
|
274
|
+
| Email | Nodemailer (Gmail SMTP) |
|
|
275
|
+
| Frontend | React 19, React Router |
|
|
276
|
+
| Build System | Turborepo + npm workspaces |
|
|
277
|
+
| API Docs | Swagger UI (OpenAPI 3.0) |
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## License
|
|
282
|
+
|
|
283
|
+
MIT
|