dolphin-server-modules 2.11.0 → 2.11.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.
Files changed (100) hide show
  1. package/TUTORIAL_NEPALI.md +181 -0
  2. package/dist/adapters/mongoose/index.d.ts +4 -4
  3. package/dist/adapters/mongoose/index.js.map +1 -1
  4. package/dist/adapters/mongoose/index.test.d.ts +1 -0
  5. package/dist/adapters/mongoose/index.test.js +145 -0
  6. package/dist/adapters/mongoose/index.test.js.map +1 -0
  7. package/dist/adapters/mongoose/integration.test.d.ts +5 -0
  8. package/dist/adapters/mongoose/integration.test.js +217 -0
  9. package/dist/adapters/mongoose/integration.test.js.map +1 -0
  10. package/dist/ai/dolphin-agent/agent.d.ts +5 -0
  11. package/dist/ai/dolphin-agent/agent.js +93 -35
  12. package/dist/ai/dolphin-agent/agent.js.map +1 -1
  13. package/dist/ai/dolphin-agent/config.js +30 -37
  14. package/dist/ai/dolphin-agent/config.js.map +1 -1
  15. package/dist/auth/auth.test.d.ts +1 -0
  16. package/dist/auth/auth.test.js +286 -0
  17. package/dist/auth/auth.test.js.map +1 -0
  18. package/dist/authController/authController.test.d.ts +1 -0
  19. package/dist/authController/authController.test.js +359 -0
  20. package/dist/authController/authController.test.js.map +1 -0
  21. package/dist/bin/cli.js +494 -165
  22. package/dist/bin/cli.js.map +1 -1
  23. package/dist/client.test.d.ts +22 -0
  24. package/dist/client.test.js +573 -0
  25. package/dist/client.test.js.map +1 -0
  26. package/dist/controller/controller.test.d.ts +1 -0
  27. package/dist/controller/controller.test.js +37 -0
  28. package/dist/controller/controller.test.js.map +1 -0
  29. package/dist/curd/crud.test.d.ts +1 -0
  30. package/dist/curd/crud.test.js +104 -0
  31. package/dist/curd/crud.test.js.map +1 -0
  32. package/dist/demo-server.d.ts +1 -0
  33. package/dist/demo-server.js +191 -0
  34. package/dist/demo-server.js.map +1 -0
  35. package/dist/djson/djson.test.d.ts +1 -0
  36. package/dist/djson/djson.test.js +200 -0
  37. package/dist/djson/djson.test.js.map +1 -0
  38. package/dist/dolphin-bench.d.ts +1 -0
  39. package/dist/dolphin-bench.js +63 -0
  40. package/dist/dolphin-bench.js.map +1 -0
  41. package/dist/hard-performance-test.d.ts +1 -0
  42. package/dist/hard-performance-test.js +97 -0
  43. package/dist/hard-performance-test.js.map +1 -0
  44. package/dist/middleware/zod.test.d.ts +1 -0
  45. package/dist/middleware/zod.test.js +74 -0
  46. package/dist/middleware/zod.test.js.map +1 -0
  47. package/dist/performance-test.d.ts +1 -0
  48. package/dist/performance-test.js +92 -0
  49. package/dist/performance-test.js.map +1 -0
  50. package/dist/real-test-mongoose.d.ts +1 -0
  51. package/dist/real-test-mongoose.js +104 -0
  52. package/dist/real-test-mongoose.js.map +1 -0
  53. package/dist/realtime/camera.d.ts +119 -0
  54. package/dist/realtime/camera.js +299 -0
  55. package/dist/realtime/camera.js.map +1 -0
  56. package/dist/realtime/camera.test.d.ts +1 -0
  57. package/dist/realtime/camera.test.js +345 -0
  58. package/dist/realtime/camera.test.js.map +1 -0
  59. package/dist/realtime/index.d.ts +2 -0
  60. package/dist/realtime/index.js +2 -0
  61. package/dist/realtime/index.js.map +1 -1
  62. package/dist/realtime/realtime.test.d.ts +1 -0
  63. package/dist/realtime/realtime.test.js +623 -0
  64. package/dist/realtime/realtime.test.js.map +1 -0
  65. package/dist/realtime/rtsp.d.ts +65 -0
  66. package/dist/realtime/rtsp.js +410 -0
  67. package/dist/realtime/rtsp.js.map +1 -0
  68. package/dist/realtime/rtsp.test.d.ts +1 -0
  69. package/dist/realtime/rtsp.test.js +361 -0
  70. package/dist/realtime/rtsp.test.js.map +1 -0
  71. package/dist/router/router.test.d.ts +1 -0
  72. package/dist/router/router.test.js +45 -0
  73. package/dist/router/router.test.js.map +1 -0
  74. package/dist/server/server.test.d.ts +1 -0
  75. package/dist/server/server.test.js +299 -0
  76. package/dist/server/server.test.js.map +1 -0
  77. package/dist/services/ai-service.js +22 -11
  78. package/dist/services/ai-service.js.map +1 -1
  79. package/dist/signaling/signaling.test.d.ts +1 -0
  80. package/dist/signaling/signaling.test.js +112 -0
  81. package/dist/signaling/signaling.test.js.map +1 -0
  82. package/dist/swagger/swagger.js +31 -31
  83. package/dist/swagger/swagger.test.d.ts +1 -0
  84. package/dist/swagger/swagger.test.js +38 -0
  85. package/dist/swagger/swagger.test.js.map +1 -0
  86. package/dist/templates/index.d.ts +6 -0
  87. package/dist/templates/index.js +282 -105
  88. package/dist/templates/index.js.map +1 -1
  89. package/dist/test-2fa-real.d.ts +1 -0
  90. package/dist/test-2fa-real.js +105 -0
  91. package/dist/test-2fa-real.js.map +1 -0
  92. package/dist/test-dolphin.d.ts +1 -0
  93. package/dist/test-dolphin.js +98 -0
  94. package/dist/test-dolphin.js.map +1 -0
  95. package/dist/utils/ctx.d.ts +50 -0
  96. package/dist/utils/ctx.js +82 -0
  97. package/dist/utils/ctx.js.map +1 -0
  98. package/package.json +155 -45
  99. package/scripts/client.js +838 -0
  100. package/scripts/dolphin-persist.js +211 -0
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+ import { generateSwagger, zodToJsonSchema } from "./swagger";
3
+ describe("Dolphin Swagger", () => {
4
+ it("should parse Zod string", () => {
5
+ const s = z.string();
6
+ expect(zodToJsonSchema(s)).toEqual({ type: "string" });
7
+ });
8
+ it("should parse Zod object", () => {
9
+ const s = z.object({
10
+ name: z.string(),
11
+ age: z.number().optional()
12
+ });
13
+ const parsed = zodToJsonSchema(s);
14
+ expect(parsed.type).toBe("object");
15
+ expect(parsed.properties.name.type).toBe("string");
16
+ expect(parsed.properties.age.type).toBe("number");
17
+ expect(parsed.required).toEqual(["name"]);
18
+ });
19
+ it("should generate swagger JSON", () => {
20
+ const userSchema = z.object({ email: z.string() });
21
+ const docs = generateSwagger({
22
+ title: "Test API",
23
+ version: "1.0.0",
24
+ modules: [
25
+ {
26
+ path: "/users",
27
+ method: "post",
28
+ schema: userSchema,
29
+ description: "Create user"
30
+ }
31
+ ]
32
+ });
33
+ expect(docs.openapi).toBe("3.0.0");
34
+ expect(docs.info.title).toBe("Test API");
35
+ expect(docs.paths["/users"]["post"].requestBody.content["application/json"].schema.type).toBe("object");
36
+ });
37
+ });
38
+ //# sourceMappingURL=swagger.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swagger.test.js","sourceRoot":"","sources":["../../src/swagger/swagger.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE7D,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;QACrB,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;YACjB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAC3B,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,eAAe,CAAC;YAC3B,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,MAAM;oBACd,MAAM,EAAE,UAAU;oBAClB,WAAW,EAAE,aAAa;iBAC3B;aACF;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1G,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -2,8 +2,14 @@ export declare const TEMPLATES: {
2
2
  app: string;
3
3
  mongoose: string;
4
4
  sequelize: string;
5
+ redis: string;
5
6
  auth: string;
6
7
  crud: (name: string) => string;
7
8
  crudModel: (name: string) => string;
8
9
  authModel: string;
10
+ model: (name: string) => string;
11
+ middleware: (name: string) => string;
12
+ route: (name: string) => string;
13
+ service: (name: string) => string;
14
+ env: string;
9
15
  };
@@ -1,112 +1,289 @@
1
1
  export const TEMPLATES = {
2
- app: `import { createDolphinServer } from 'dolphin-server-modules/server';
3
- import { createMongooseAdapter } from 'dolphin-server-modules/adapters/mongoose';
4
- import { createDolphinAuthController } from 'dolphin-server-modules/auth-controller';
5
-
6
- const app = createDolphinServer();
7
-
8
- // DB Connection & Adapter
9
- const dbAdapter = createMongooseAdapter(process.env.MONGO_URI || 'mongodb://localhost:27017/dolphin_db');
10
-
11
- // Auth Setup
12
- const auth = createDolphinAuthController({
13
- adapter: dbAdapter,
14
- jwtSecret: process.env.JWT_SECRET || 'dolphin_secret'
15
- });
16
-
17
- app.post('/api/auth/register', auth.register);
18
- app.post('/api/auth/login', auth.login);
19
-
20
- app.listen(3000, () => console.log('🐬 Dolphin Production Server is swimming on port 3000'));
2
+ app: `import { createDolphinServer } from 'dolphin-server-modules/server';
3
+ import { createMongooseAdapter } from 'dolphin-server-modules/adapters/mongoose';
4
+ import { createDolphinAuthController } from 'dolphin-server-modules/auth-controller';
5
+ import { connectDB } from './config/db.js';
6
+ import { User, RefreshToken } from './models/User.js';
7
+
8
+ const app = createDolphinServer();
9
+
10
+ // Global Error Handler — server crash बाट ą¤¬ą¤šą¤¾ą¤‰ą¤ą¤›
11
+ app.use(async (ctx, next) => {
12
+ try { if (next) await next(); }
13
+ catch (error) {
14
+ console.error('šŸ”„ ERROR:', error.message);
15
+ ctx.status(500).json({ success: false, message: 'Internal Server Error' });
16
+ }
17
+ });
18
+
19
+ // DB connect
20
+ connectDB(process.env.MONGO_URI || 'mongodb://localhost:27017/dolphin_db');
21
+
22
+ // Mongoose Adapter
23
+ const db = createMongooseAdapter({ User, RefreshToken });
24
+
25
+ // Auth
26
+ const auth = createDolphinAuthController({
27
+ adapter: db,
28
+ jwtSecret: process.env.JWT_SECRET || 'change_in_production',
29
+ });
30
+
31
+ app.post('/api/auth/register', auth.register);
32
+ app.post('/api/auth/login', auth.login);
33
+ app.post('/api/auth/refresh', auth.refresh);
34
+ app.post('/api/auth/logout', auth.middleware(), auth.logout);
35
+
36
+ app.get('/health', (ctx) => ({ status: 'ok', ts: new Date().toISOString() }));
37
+
38
+ const PORT = parseInt(process.env.PORT || '3000');
39
+ app.listen(PORT, () => console.log(\`🐬 Dolphin Server swimming on port \${PORT}\`));
21
40
  `,
22
- mongoose: `import mongoose from 'mongoose';
23
- export const connectDB = async (uri) => {
24
- try {
25
- await mongoose.connect(uri);
26
- console.log('āœ… MongoDB Connected');
27
- } catch (e) {
28
- console.error('āŒ DB Error:', e);
29
- }
30
- };`,
31
- sequelize: `import { Sequelize } from 'sequelize';
32
- export const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
33
- host: process.env.DB_HOST || 'localhost',
34
- dialect: 'mysql',
35
- logging: false
36
- });
37
-
38
- export const connectDB = async () => {
39
- try {
40
- await sequelize.authenticate();
41
- console.log('āœ… MySQL/Sequelize Connected');
42
- } catch (e) {
43
- console.error('āŒ DB Error:', e);
44
- }
45
- };`,
46
- auth: `import { createDolphinAuthController } from 'dolphin-server-modules/auth-controller';
47
- import { User } from '../models/User.js';
48
-
49
- // This is a production-ready Auth Controller using Dolphin Modules
50
- export const auth = createDolphinAuthController({
51
- secret: process.env.JWT_SECRET || 'your_ultra_secret_key',
52
- model: User, // In a real app, you'd pass a Database Adapter
53
- issuer: 'DolphinApp'
54
- });
55
-
56
- export const register = auth.register;
57
- export const login = auth.login;
41
+ mongoose: `import mongoose from 'mongoose';
42
+
43
+ export const connectDB = async (uri) => {
44
+ try {
45
+ await mongoose.connect(uri, { serverSelectionTimeoutMS: 5000 });
46
+ console.log('āœ… MongoDB Connected:', mongoose.connection.host);
47
+ } catch (e) {
48
+ console.error('āŒ MongoDB Error:', e.message);
49
+ process.exit(1);
50
+ }
51
+ };
52
+
53
+ mongoose.connection.on('disconnected', () => console.warn('āš ļø MongoDB disconnected'));
54
+ mongoose.connection.on('error', (err) => console.error('āŒ MongoDB:', err.message));
58
55
  `,
59
- crud: (name) => `import { createCrudController } from 'dolphin-server-modules/crud';
60
- import { ${name} } from '../models/${name}.js';
61
-
62
- // Fully automated CRUD controller for ${name}
63
- export const ${name.toLowerCase()}Controller = createCrudController(
64
- ${name}, // Mongoose Model
65
- '${name.toLowerCase()}s', // Collection Name
66
- { softDelete: true, enforceOwnership: true }
67
- );
68
-
69
- export const getAll = ${name.toLowerCase()}Controller.getAll;
70
- export const getOne = ${name.toLowerCase()}Controller.getOne;
71
- export const create = ${name.toLowerCase()}Controller.create;
72
- export const update = ${name.toLowerCase()}Controller.update;
73
- export const remove = ${name.toLowerCase()}Controller.delete;
56
+ sequelize: `import { Sequelize } from 'sequelize';
57
+
58
+ export const sequelize = new Sequelize(
59
+ process.env.DB_NAME || 'dolphin_db',
60
+ process.env.DB_USER || 'root',
61
+ process.env.DB_PASS || '',
62
+ {
63
+ host: process.env.DB_HOST || 'localhost',
64
+ dialect: process.env.DB_DIALECT || 'mysql',
65
+ logging: process.env.NODE_ENV === 'development' ? console.log : false,
66
+ pool: { max: 10, min: 0, acquire: 30000, idle: 10000 },
67
+ }
68
+ );
69
+
70
+ export const connectDB = async () => {
71
+ try {
72
+ await sequelize.authenticate();
73
+ console.log('āœ… Sequelize Connected:', process.env.DB_HOST || 'localhost');
74
+ await sequelize.sync({ alter: process.env.NODE_ENV === 'development' });
75
+ } catch (e) {
76
+ console.error('āŒ Sequelize Error:', e.message); process.exit(1);
77
+ }
78
+ };
74
79
  `,
75
- crudModel: (name) => `import mongoose from 'mongoose';
76
-
77
- const ${name.toLowerCase()}Schema = new mongoose.Schema({
78
- userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
79
- title: { type: String, required: true },
80
- description: { type: String },
81
- status: { type: String, enum: ['pending', 'completed'], default: 'pending' }
82
- }, { timestamps: true });
83
-
84
- export const ${name} = mongoose.model('${name}', ${name.toLowerCase()}Schema);
80
+ redis: `import { createClient } from 'redis';
81
+
82
+ const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
83
+
84
+ export const redisClient = createClient({ url: REDIS_URL });
85
+ redisClient.on('error', (err) => console.error('āŒ Redis:', err.message));
86
+ redisClient.on('connect', () => console.log('āœ… Redis Connected:', REDIS_URL));
87
+ redisClient.on('reconnecting',() => console.warn('āš ļø Redis reconnecting...'));
88
+
89
+ export const connectRedis = async () => {
90
+ await redisClient.connect().catch(e => { console.error('āŒ Redis:', e.message); process.exit(1); });
91
+ };
92
+
93
+ export const cache = {
94
+ set: (key, value, ttl = 3600) => redisClient.setEx(key, ttl, JSON.stringify(value)),
95
+ get: async (key) => { const v = await redisClient.get(key); return v ? JSON.parse(v) : null; },
96
+ del: (key) => redisClient.del(key),
97
+ exists: async (key) => (await redisClient.exists(key)) === 1,
98
+ };
99
+ `,
100
+ auth: `import { createDolphinAuthController } from 'dolphin-server-modules/auth-controller';
101
+ import { db } from './adapter.js'; // ą¤¤ą¤Ŗą¤¾ą¤ˆą¤‚ą¤•ą„‹ createMongooseAdapter instance
102
+
103
+ export const auth = createDolphinAuthController({
104
+ adapter: db,
105
+ jwtSecret: process.env.JWT_SECRET || 'change_in_production',
106
+ accessTokenExpiry: '15m',
107
+ refreshTokenExpiry: '7d',
108
+ });
109
+
110
+ export const { register, login, refresh, logout, middleware } = auth;
111
+ `,
112
+ crud: (name) => `import { createCrudController } from 'dolphin-server-modules/crud';
113
+ import { db } from '../config/adapter.js';
114
+
115
+ const ctrl = createCrudController(db, '${name}', {
116
+ softDelete: true,
117
+ enforceOwnership: false,
118
+ });
119
+
120
+ export const { getAll, getOne, create, update } = ctrl;
121
+ export const remove = ctrl.delete;
122
+ `,
123
+ crudModel: (name) => `import mongoose from 'mongoose';
124
+
125
+ const ${name.toLowerCase()}Schema = new mongoose.Schema(
126
+ {
127
+ title: { type: String, required: true, trim: true },
128
+ description: { type: String, default: '' },
129
+ status: { type: String, enum: ['active','inactive'], default: 'active' },
130
+ userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
131
+ },
132
+ { timestamps: true, versionKey: false }
133
+ );
134
+
135
+ ${name.toLowerCase()}Schema.index({ userId: 1, status: 1 });
136
+ ${name.toLowerCase()}Schema.index({ createdAt: -1 });
137
+
138
+ export const ${name} = mongoose.model('${name}', ${name.toLowerCase()}Schema);
139
+ `,
140
+ authModel: `import mongoose from 'mongoose';
141
+
142
+ const userSchema = new mongoose.Schema(
143
+ {
144
+ email: { type: String, required: true, unique: true, lowercase: true, trim: true },
145
+ password: { type: String, required: true },
146
+ role: { type: String, enum: ['user','admin','moderator'], default: 'user' },
147
+ twoFactorEnabled: { type: Boolean, default: false },
148
+ twoFactorSecret: { type: String, default: null },
149
+ pending2FASecret: { type: String, default: null },
150
+ recoveryCodes: { type: [String], default: [] },
151
+ isActive: { type: Boolean, default: true },
152
+ lastLoginAt: { type: Date, default: null },
153
+ },
154
+ { timestamps: true, versionKey: false }
155
+ );
156
+ userSchema.index({ email: 1 });
157
+ export const User = mongoose.model('User', userSchema);
158
+
159
+ const refreshTokenSchema = new mongoose.Schema(
160
+ {
161
+ token: { type: String, required: true, unique: true, index: true },
162
+ userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
163
+ expiresAt: { type: Date, required: true },
164
+ twoFactorVerified: { type: Boolean, default: false },
165
+ userAgent: { type: String, default: null },
166
+ ip: { type: String, default: null },
167
+ },
168
+ { timestamps: true, versionKey: false }
169
+ );
170
+ refreshTokenSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
171
+ export const RefreshToken = mongoose.model('RefreshToken', refreshTokenSchema);
172
+ `,
173
+ model: (name) => `import mongoose from 'mongoose';
174
+
175
+ const ${name.toLowerCase()}Schema = new mongoose.Schema(
176
+ {
177
+ name: { type: String, required: true, trim: true, maxlength: 200 },
178
+ description: { type: String, default: '', maxlength: 2000 },
179
+ isActive: { type: Boolean, default: true },
180
+ },
181
+ {
182
+ timestamps: true,
183
+ versionKey: false,
184
+ toJSON: {
185
+ transform: (_, ret) => { ret.id = ret._id?.toString(); delete ret._id; return ret; }
186
+ }
187
+ }
188
+ );
189
+
190
+ ${name.toLowerCase()}Schema.index({ name: 1 });
191
+ ${name.toLowerCase()}Schema.index({ isActive: 1, createdAt: -1 });
192
+
193
+ export const ${name} = mongoose.model('${name}', ${name.toLowerCase()}Schema);
194
+ `,
195
+ middleware: (name) => `/**
196
+ * ${name} Middleware
197
+ * Usage: app.use(${name.toLowerCase()}Middleware) वा app.get('/route', ${name.toLowerCase()}Middleware, handler)
198
+ */
199
+ export const ${name.toLowerCase()}Middleware = async (ctx, next) => {
200
+ // TODO: ą¤¤ą¤Ŗą¤¾ą¤ˆą¤‚ą¤•ą„‹ logic यहाँ ą¤²ą„‡ą¤–ą„ą¤Øą„ą¤¹ą„‹ą¤øą„
201
+ console.log(\`[${name}] \${ctx.req.method} \${ctx.req.url}\`);
202
+ if (next) await next();
203
+ };
204
+ `,
205
+ route: (name) => `import { createDolphinRouter } from 'dolphin-server-modules/router';
206
+
207
+ const router = createDolphinRouter();
208
+ const base = '/${name.toLowerCase()}s';
209
+
210
+ router.get(base, async (ctx) => {
211
+ return { success: true, data: [], message: '${name} list' };
212
+ });
213
+
214
+ router.get(\`\${base}/:id\`, async (ctx) => {
215
+ return { success: true, data: { id: ctx.params.id } };
216
+ });
217
+
218
+ router.post(base, async (ctx) => {
219
+ return ctx.status(201).json({ success: true, data: ctx.body });
220
+ });
221
+
222
+ router.put(\`\${base}/:id\`, async (ctx) => {
223
+ return { success: true, data: { id: ctx.params.id, ...ctx.body } };
224
+ });
225
+
226
+ router.delete(\`\${base}/:id\`, async (ctx) => {
227
+ return { success: true, data: { id: ctx.params.id, deleted: true } };
228
+ });
229
+
230
+ export const ${name.toLowerCase()}Router = router;
231
+ `,
232
+ service: (name) => `/**
233
+ * ${name}Service — Business logic layer
234
+ * Controller र Database ą¤•ą„‹ ą¤¬ą„€ą¤šą¤•ą„‹ layer
235
+ */
236
+ export class ${name}Service {
237
+
238
+ static async getAll(filter = {}) {
239
+ // TODO: DB query
240
+ return [];
241
+ }
242
+
243
+ static async getById(id) {
244
+ // TODO: DB findById
245
+ return null;
246
+ }
247
+
248
+ static async create(data) {
249
+ // TODO: DB create
250
+ return { id: Date.now().toString(), ...data, createdAt: new Date() };
251
+ }
252
+
253
+ static async update(id, data) {
254
+ // TODO: DB update
255
+ return { id, ...data, updatedAt: new Date() };
256
+ }
257
+
258
+ static async delete(id) {
259
+ // TODO: DB delete
260
+ return { id, deleted: true };
261
+ }
262
+ }
263
+ `,
264
+ env: `# 🐬 Dolphin Framework — Environment Variables
265
+ # āš ļø ą¤Æą„‹ file .gitignore मा ą¤°ą¤¾ą¤–ą„ą¤Øą„ą¤¹ą„‹ą¤øą„ — production मा NEVER commit!
266
+
267
+ NODE_ENV=development
268
+ PORT=3000
269
+
270
+ # MongoDB
271
+ MONGO_URI=mongodb://localhost:27017/dolphin_db
272
+
273
+ # JWT Secret (ą¤•ą¤®ą„ą¤¤ą„€ą¤®ą¤¾ 32 chars)
274
+ JWT_SECRET=change_this_ultra_secret_key_in_production_32chars
275
+
276
+ # Redis (optional — realtime scaling)
277
+ # REDIS_URL=redis://localhost:6379
278
+
279
+ # AI Keys (dolphin chat/generate ą¤•ą„‹ लागि)
280
+ # GEMINI_API_KEY=your_key_here
281
+ # GROQ_API_KEY=your_key_here
282
+ # OPENAI_API_KEY=your_key_here
283
+
284
+ # Local Ollama (optional)
285
+ # USE_OLLAMA=true
286
+ # OLLAMA_MODEL=gemma3:latest
85
287
  `,
86
- authModel: `import mongoose from 'mongoose';
87
-
88
- const userSchema = new mongoose.Schema({
89
- email: { type: String, required: true, unique: true },
90
- password: { type: String, required: true },
91
- role: { type: String, default: 'user' },
92
- twoFactorEnabled: { type: Boolean, default: false },
93
- twoFactorSecret: { type: String, default: null },
94
- pending2FASecret: { type: String, default: null },
95
- recoveryCodes: { type: [String], default: [] }
96
- }, { timestamps: true });
97
-
98
- export const User = mongoose.model('User', userSchema);
99
-
100
- const refreshTokenSchema = new mongoose.Schema({
101
- token: { type: String, required: true, unique: true },
102
- userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
103
- expiresAt: { type: Date, required: true },
104
- twoFactorVerified: { type: Boolean, default: false }
105
- }, { timestamps: true });
106
-
107
- refreshTokenSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 }); // Auto-delete expired tokens
108
-
109
- export const RefreshToken = mongoose.model('RefreshToken', refreshTokenSchema);
110
- `
111
288
  };
112
289
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG;IACrB,GAAG,EAAE;;;;;;;;;;;;;;;;;;;CAmBR;IACG,QAAQ,EAAE;;;;;;;;GAQX;IACC,SAAS,EAAE;;;;;;;;;;;;;;GAcZ;IACC,IAAI,EAAE;;;;;;;;;;;;CAYT;IACG,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC;WACjB,IAAI,sBAAsB,IAAI;;yCAEA,IAAI;eAC9B,IAAI,CAAC,WAAW,EAAE;MAC3B,IAAI;OACH,IAAI,CAAC,WAAW,EAAE;;;;wBAID,IAAI,CAAC,WAAW,EAAE;wBAClB,IAAI,CAAC,WAAW,EAAE;wBAClB,IAAI,CAAC,WAAW,EAAE;wBAClB,IAAI,CAAC,WAAW,EAAE;wBAClB,IAAI,CAAC,WAAW,EAAE;CACzC;IACG,SAAS,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC;;QAEzB,IAAI,CAAC,WAAW,EAAE;;;;;;;eAOX,IAAI,sBAAsB,IAAI,MAAM,IAAI,CAAC,WAAW,EAAE;CACpE;IACG,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;CAwBd;CACA,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG;IAErB,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCR;IAEG,QAAQ,EAAE;;;;;;;;;;;;;;CAcb;IAEG,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;CAuBd;IAEG,KAAK,EAAE;;;;;;;;;;;;;;;;;;;CAmBV;IAEG,IAAI,EAAE;;;;;;;;;;;CAWT;IAEG,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC;;;yCAGa,IAAI;;;;;;;CAO5C;IAEG,SAAS,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC;;QAEzB,IAAI,CAAC,WAAW,EAAE;;;;;;;;;;EAUxB,IAAI,CAAC,WAAW,EAAE;EAClB,IAAI,CAAC,WAAW,EAAE;;eAEL,IAAI,sBAAsB,IAAI,MAAM,IAAI,CAAC,WAAW,EAAE;CACpE;IAEG,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCd;IAEG,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC;;QAErB,IAAI,CAAC,WAAW,EAAE;;;;;;;;;;;;;;;EAexB,IAAI,CAAC,WAAW,EAAE;EAClB,IAAI,CAAC,WAAW,EAAE;;eAEL,IAAI,sBAAsB,IAAI,MAAM,IAAI,CAAC,WAAW,EAAE;CACpE;IAEG,UAAU,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC;KAC7B,IAAI;oBACW,IAAI,CAAC,WAAW,EAAE,sCAAsC,IAAI,CAAC,WAAW,EAAE;;eAE/E,IAAI,CAAC,WAAW,EAAE;;mBAEd,IAAI;;;CAGtB;IAEG,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC;;;iBAGZ,IAAI,CAAC,WAAW,EAAE;;;gDAGa,IAAI;;;;;;;;;;;;;;;;;;;eAmBrC,IAAI,CAAC,WAAW,EAAE;CAChC;IAEG,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC;KAC1B,IAAI;;;eAGM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BlB;IAEG,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;CAuBR;CACA,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,105 @@
1
+ // test-2fa-real.ts
2
+ import { createAuth } from "./auth/auth";
3
+ import crypto from "node:crypto";
4
+ import argon2 from "argon2";
5
+ // Helper to simulate a TOTP app (reusing logic from auth.ts)
6
+ const BASE32_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
7
+ const base32Decode = (str) => {
8
+ str = str.replace(/=/g, '').toUpperCase();
9
+ let bits = 0, value = 0;
10
+ const bytes = [];
11
+ for (let i = 0; i < str.length; i++) {
12
+ const idx = BASE32_CHARS.indexOf(str[i]);
13
+ value = (value << 5) | idx;
14
+ bits += 5;
15
+ if (bits >= 8) {
16
+ bytes.push((value >>> (bits - 8)) & 255);
17
+ bits -= 8;
18
+ }
19
+ }
20
+ return Buffer.from(bytes);
21
+ };
22
+ const generateTOTP = (secretBase32, timestamp = Date.now()) => {
23
+ const counter = Math.floor(timestamp / 30000);
24
+ const counterBuf = Buffer.alloc(8);
25
+ counterBuf.writeBigInt64BE(BigInt(counter), 0);
26
+ const secret = base32Decode(secretBase32);
27
+ const hmac = crypto.createHmac('sha1', secret);
28
+ hmac.update(counterBuf);
29
+ const hash = hmac.digest();
30
+ const offset = hash[hash.length - 1] & 0xf;
31
+ const code = (hash.readUInt32BE(offset) & 0x7fffffff) % 1000000;
32
+ return code.toString().padStart(6, '0');
33
+ };
34
+ async function run2FATest() {
35
+ console.log("šŸ” Starting 'Real' 2FA Flow Test...\n");
36
+ const auth = createAuth({ secret: 'test-secret' });
37
+ // 1. Mock DB state
38
+ let mockUser = {
39
+ id: "user123",
40
+ email: "test@example.com",
41
+ password: await argon2.hash("password123"),
42
+ twoFactorEnabled: false,
43
+ twoFactorSecret: null,
44
+ pending2FASecret: null,
45
+ recoveryCodes: []
46
+ };
47
+ const db = {
48
+ findUserById: async () => mockUser,
49
+ findUserByEmail: async () => mockUser,
50
+ updateUser: async (id, data) => {
51
+ mockUser = { ...mockUser, ...data };
52
+ return mockUser;
53
+ },
54
+ saveRefreshToken: async () => { },
55
+ findRefreshToken: async () => null,
56
+ deleteRefreshToken: async () => { }
57
+ };
58
+ // --- STEP 1: Enable 2FA ---
59
+ console.log("Step 1: Enabling 2FA (Generating Secret)...");
60
+ const setup = await auth.enable2FA(db, mockUser.id);
61
+ console.log("āœ… Secret Generated:", setup.secret);
62
+ console.log("āœ… URI:", setup.uri);
63
+ // --- STEP 2: Verify 2FA ---
64
+ console.log("\nStep 2: Verifying 2FA with TOTP Token...");
65
+ const realToken = generateTOTP(setup.secret);
66
+ console.log("šŸ“± Simulated App Token:", realToken);
67
+ const verifyResult = await auth.verify2FA(db, mockUser.id, realToken);
68
+ console.log("āœ… 2FA Verified! Recovery Codes:", verifyResult.recoveryCodes);
69
+ console.log("āœ… User 2FA Status:", mockUser.twoFactorEnabled ? "ENABLED" : "FAILED");
70
+ // --- STEP 3: Login without TOTP (Should fail) ---
71
+ console.log("\nStep 3: Attempting Login WITHOUT TOTP...");
72
+ try {
73
+ await auth.login(db, { email: mockUser.email, password: "password123" });
74
+ console.log("āŒ FAILED: Login succeeded without TOTP!");
75
+ }
76
+ catch (err) {
77
+ console.log("āœ… SUCCESS: Login denied as expected:", err.message);
78
+ }
79
+ // --- STEP 4: Login with correct TOTP ---
80
+ console.log("\nStep 4: Attempting Login WITH correct TOTP...");
81
+ const loginToken = generateTOTP(setup.secret);
82
+ const loginResult = await auth.login(db, { email: mockUser.email, password: "password123", totp: loginToken });
83
+ console.log("āœ… SUCCESS: Logged in! Access Token length:", loginResult.accessToken.length);
84
+ // --- STEP 5: Test Recovery Codes ---
85
+ console.log("\nStep 5: Testing Recovery Code Login...");
86
+ const backupCode = verifyResult.recoveryCodes[0];
87
+ const recoveryResult = await auth.login(db, {
88
+ email: mockUser.email,
89
+ password: "password123",
90
+ recovery: backupCode
91
+ });
92
+ console.log("āœ… SUCCESS: Logged in using recovery code!");
93
+ console.log("āœ… Remaining recovery codes count:", mockUser.recoveryCodes.length);
94
+ // --- STEP 6: Disable 2FA ---
95
+ console.log("\nStep 6: Disabling 2FA...");
96
+ const disableToken = generateTOTP(setup.secret);
97
+ await auth.disable2FA(db, mockUser.id, disableToken);
98
+ console.log("āœ… SUCCESS: 2FA Disabled. Status:", mockUser.twoFactorEnabled ? "ENABLED (Error)" : "DISABLED");
99
+ console.log("\nšŸŽŠ ALL 2FA FLOWS COMPLETED SUCCESSFULLY! šŸŽŠ");
100
+ }
101
+ run2FATest().catch(err => {
102
+ console.error("āŒ TEST FAILED:", err);
103
+ process.exit(1);
104
+ });
105
+ //# sourceMappingURL=test-2fa-real.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-2fa-real.js","sourceRoot":"","sources":["../src/test-2fa-real.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};