express-genix 1.1.4 → 2.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/LICENSE +21 -0
- package/README.md +204 -259
- package/index.js +229 -113
- package/lib/cleanup.js +41 -129
- package/lib/features.js +239 -0
- package/lib/generator.js +286 -204
- package/lib/utils.js +43 -91
- package/package.json +81 -63
- package/templates/cicd/github-actions.yml.ejs +70 -0
- package/templates/config/database.mongo.js.ejs +29 -33
- package/templates/config/database.postgres.js.ejs +41 -40
- package/templates/config/database.prisma.js.ejs +26 -0
- package/templates/config/redis.js.ejs +28 -0
- package/templates/config/schema.prisma.ejs +20 -0
- package/templates/config/swagger.js.ejs +30 -0
- package/templates/config/websocket.js.ejs +62 -0
- package/templates/controllers/authController.js.ejs +152 -129
- package/templates/controllers/exampleController.js.ejs +92 -152
- package/templates/controllers/userController.js.ejs +52 -60
- package/templates/core/Dockerfile.ejs +41 -31
- package/templates/core/README.md.ejs +191 -179
- package/templates/core/app.js.ejs +114 -64
- package/templates/core/docker-compose.yml.ejs +59 -47
- package/templates/core/dockerignore.ejs +7 -0
- package/templates/core/env.ejs +25 -19
- package/templates/core/env.example.ejs +26 -0
- package/templates/core/eslintrc.json.ejs +50 -20
- package/templates/core/gitignore.ejs +51 -51
- package/templates/core/healthcheck.js.ejs +24 -24
- package/templates/core/jest.config.js.ejs +19 -22
- package/templates/core/package.json.ejs +70 -33
- package/templates/core/prettierrc.json.ejs +11 -11
- package/templates/core/server.js.ejs +64 -48
- package/templates/core/tsconfig.json.ejs +19 -0
- package/templates/middleware/auth.js.ejs +80 -66
- package/templates/middleware/cache.js.ejs +67 -0
- package/templates/middleware/errorHandler.js.ejs +50 -46
- package/templates/middleware/requestId.js.ejs +9 -0
- package/templates/middleware/validation.js.ejs +109 -47
- package/templates/migrations/create-users.js.ejs +50 -0
- package/templates/migrations/seed-users.js.ejs +34 -0
- package/templates/migrations/sequelizerc.ejs +8 -0
- package/templates/models/User.mongo.js.ejs +29 -29
- package/templates/models/User.postgres.js.ejs +40 -40
- package/templates/models/index.mongo.js.ejs +7 -7
- package/templates/models/index.postgres.js.ejs +11 -11
- package/templates/routes/authRoutes.js.ejs +222 -13
- package/templates/routes/exampleRoutes.js.ejs +100 -12
- package/templates/routes/index.js.ejs +34 -24
- package/templates/routes/userRoutes.js.ejs +78 -15
- package/templates/services/authService.js.ejs +111 -35
- package/templates/services/exampleService.js.ejs +112 -112
- package/templates/services/userService.mongodb.js.ejs +33 -33
- package/templates/services/userService.postgres.js.ejs +30 -30
- package/templates/services/userService.prisma.js.ejs +36 -0
- package/templates/tests/auth.test.js.ejs +83 -66
- package/templates/tests/example.test.js.ejs +109 -112
- package/templates/tests/setup.js.ejs +11 -11
- package/templates/tests/users.test.js.ejs +42 -42
- package/templates/utils/envValidator.js.ejs +23 -0
- package/templates/utils/errors.js.ejs +12 -12
- package/templates/utils/logger.js.ejs +37 -28
- package/templates/utils/response.js.ejs +28 -0
- package/templates/utils/validators.js.ejs +34 -34
- package/templates/config/swagger.json.ejs +0 -194
- package/templates/core/index.js.ejs +0 -24
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
async up(queryInterface, Sequelize) {
|
|
5
|
+
await queryInterface.createTable('users', {
|
|
6
|
+
id: {
|
|
7
|
+
type: Sequelize.UUID,
|
|
8
|
+
defaultValue: Sequelize.UUIDV4,
|
|
9
|
+
primaryKey: true,
|
|
10
|
+
allowNull: false,
|
|
11
|
+
},
|
|
12
|
+
username: {
|
|
13
|
+
type: Sequelize.STRING(50),
|
|
14
|
+
allowNull: false,
|
|
15
|
+
unique: true,
|
|
16
|
+
},
|
|
17
|
+
email: {
|
|
18
|
+
type: Sequelize.STRING(255),
|
|
19
|
+
allowNull: false,
|
|
20
|
+
unique: true,
|
|
21
|
+
},
|
|
22
|
+
password: {
|
|
23
|
+
type: Sequelize.STRING(255),
|
|
24
|
+
allowNull: false,
|
|
25
|
+
},
|
|
26
|
+
role: {
|
|
27
|
+
type: Sequelize.STRING(20),
|
|
28
|
+
allowNull: false,
|
|
29
|
+
defaultValue: 'user',
|
|
30
|
+
},
|
|
31
|
+
createdAt: {
|
|
32
|
+
type: Sequelize.DATE,
|
|
33
|
+
allowNull: false,
|
|
34
|
+
defaultValue: Sequelize.literal('NOW()'),
|
|
35
|
+
},
|
|
36
|
+
updatedAt: {
|
|
37
|
+
type: Sequelize.DATE,
|
|
38
|
+
allowNull: false,
|
|
39
|
+
defaultValue: Sequelize.literal('NOW()'),
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await queryInterface.addIndex('users', ['email'], { unique: true });
|
|
44
|
+
await queryInterface.addIndex('users', ['username'], { unique: true });
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
async down(queryInterface) {
|
|
48
|
+
await queryInterface.dropTable('users');
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const bcrypt = require('bcryptjs');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
async up(queryInterface) {
|
|
7
|
+
const hashedPassword = await bcrypt.hash('Password1', 12);
|
|
8
|
+
|
|
9
|
+
await queryInterface.bulkInsert('users', [
|
|
10
|
+
{
|
|
11
|
+
id: '00000000-0000-4000-a000-000000000001',
|
|
12
|
+
username: 'admin',
|
|
13
|
+
email: 'admin@example.com',
|
|
14
|
+
password: hashedPassword,
|
|
15
|
+
role: 'admin',
|
|
16
|
+
createdAt: new Date(),
|
|
17
|
+
updatedAt: new Date(),
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: '00000000-0000-4000-a000-000000000002',
|
|
21
|
+
username: 'testuser',
|
|
22
|
+
email: 'user@example.com',
|
|
23
|
+
password: hashedPassword,
|
|
24
|
+
role: 'user',
|
|
25
|
+
createdAt: new Date(),
|
|
26
|
+
updatedAt: new Date(),
|
|
27
|
+
},
|
|
28
|
+
]);
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
async down(queryInterface) {
|
|
32
|
+
await queryInterface.bulkDelete('users', null, {});
|
|
33
|
+
},
|
|
34
|
+
};
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
const mongoose = require('mongoose');
|
|
2
|
-
|
|
3
|
-
const userSchema = new mongoose.Schema({
|
|
4
|
-
username: {
|
|
5
|
-
type: String,
|
|
6
|
-
required: [true, 'Username is required'],
|
|
7
|
-
unique: true,
|
|
8
|
-
trim: true,
|
|
9
|
-
minlength: [3, 'Username must be at least 3 characters long'],
|
|
10
|
-
maxlength: [50, 'Username must not exceed 50 characters'],
|
|
11
|
-
},
|
|
12
|
-
email: {
|
|
13
|
-
type: String,
|
|
14
|
-
required: [true, 'Email is required'],
|
|
15
|
-
unique: true,
|
|
16
|
-
lowercase: true,
|
|
17
|
-
trim: true,
|
|
18
|
-
match: [/^\S+@\S+\.\S+$/, 'Please enter a valid email address'],
|
|
19
|
-
},
|
|
20
|
-
password: {
|
|
21
|
-
type: String,
|
|
22
|
-
required: [true, 'Password is required'],
|
|
23
|
-
minlength: [
|
|
24
|
-
},
|
|
25
|
-
}, {
|
|
26
|
-
timestamps: true,
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
|
|
3
|
+
const userSchema = new mongoose.Schema({
|
|
4
|
+
username: {
|
|
5
|
+
type: String,
|
|
6
|
+
required: [true, 'Username is required'],
|
|
7
|
+
unique: true,
|
|
8
|
+
trim: true,
|
|
9
|
+
minlength: [3, 'Username must be at least 3 characters long'],
|
|
10
|
+
maxlength: [50, 'Username must not exceed 50 characters'],
|
|
11
|
+
},
|
|
12
|
+
email: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: [true, 'Email is required'],
|
|
15
|
+
unique: true,
|
|
16
|
+
lowercase: true,
|
|
17
|
+
trim: true,
|
|
18
|
+
match: [/^\S+@\S+\.\S+$/, 'Please enter a valid email address'],
|
|
19
|
+
},
|
|
20
|
+
password: {
|
|
21
|
+
type: String,
|
|
22
|
+
required: [true, 'Password is required'],
|
|
23
|
+
minlength: [8, 'Password must be at least 8 characters long'],
|
|
24
|
+
},
|
|
25
|
+
}, {
|
|
26
|
+
timestamps: true,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
|
|
30
30
|
module.exports = mongoose.model('User', userSchema);
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
const { DataTypes } = require('sequelize');
|
|
2
|
-
const { sequelize } = require('../config/database');
|
|
3
|
-
|
|
4
|
-
const User = sequelize.define('User', {
|
|
5
|
-
id: {
|
|
6
|
-
type: DataTypes.UUID,
|
|
7
|
-
defaultValue: DataTypes.UUIDV4,
|
|
8
|
-
primaryKey: true,
|
|
9
|
-
},
|
|
10
|
-
username: {
|
|
11
|
-
type: DataTypes.STRING(50),
|
|
12
|
-
allowNull: false,
|
|
13
|
-
unique: true,
|
|
14
|
-
validate: {
|
|
15
|
-
len: [3, 50],
|
|
16
|
-
notEmpty: true,
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
email: {
|
|
20
|
-
type: DataTypes.STRING,
|
|
21
|
-
allowNull: false,
|
|
22
|
-
unique: true,
|
|
23
|
-
validate: {
|
|
24
|
-
isEmail: true,
|
|
25
|
-
notEmpty: true,
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
password: {
|
|
29
|
-
type: DataTypes.STRING,
|
|
30
|
-
allowNull: false,
|
|
31
|
-
validate: {
|
|
32
|
-
len: [
|
|
33
|
-
notEmpty: true,
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
}, {
|
|
37
|
-
timestamps: true,
|
|
38
|
-
tableName: 'users',
|
|
39
|
-
});
|
|
40
|
-
|
|
1
|
+
const { DataTypes } = require('sequelize');
|
|
2
|
+
const { sequelize } = require('../config/database');
|
|
3
|
+
|
|
4
|
+
const User = sequelize.define('User', {
|
|
5
|
+
id: {
|
|
6
|
+
type: DataTypes.UUID,
|
|
7
|
+
defaultValue: DataTypes.UUIDV4,
|
|
8
|
+
primaryKey: true,
|
|
9
|
+
},
|
|
10
|
+
username: {
|
|
11
|
+
type: DataTypes.STRING(50),
|
|
12
|
+
allowNull: false,
|
|
13
|
+
unique: true,
|
|
14
|
+
validate: {
|
|
15
|
+
len: [3, 50],
|
|
16
|
+
notEmpty: true,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
email: {
|
|
20
|
+
type: DataTypes.STRING,
|
|
21
|
+
allowNull: false,
|
|
22
|
+
unique: true,
|
|
23
|
+
validate: {
|
|
24
|
+
isEmail: true,
|
|
25
|
+
notEmpty: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
password: {
|
|
29
|
+
type: DataTypes.STRING,
|
|
30
|
+
allowNull: false,
|
|
31
|
+
validate: {
|
|
32
|
+
len: [8, 255],
|
|
33
|
+
notEmpty: true,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}, {
|
|
37
|
+
timestamps: true,
|
|
38
|
+
tableName: 'users',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
41
|
module.exports = User;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// For MongoDB, we typically don't need an index file as we import models directly
|
|
2
|
-
// But you can use this file to define model relationships if needed
|
|
3
|
-
|
|
4
|
-
const User = require('./User');
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
User,
|
|
1
|
+
// For MongoDB, we typically don't need an index file as we import models directly
|
|
2
|
+
// But you can use this file to define model relationships if needed
|
|
3
|
+
|
|
4
|
+
const User = require('./User');
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
User,
|
|
8
8
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const { sequelize } = require('../config/database');
|
|
2
|
-
const User = require('./User');
|
|
3
|
-
|
|
4
|
-
// Define associations here if you have multiple models
|
|
5
|
-
// Example:
|
|
6
|
-
// User.hasMany(Post);
|
|
7
|
-
// Post.belongsTo(User);
|
|
8
|
-
|
|
9
|
-
module.exports = {
|
|
10
|
-
sequelize,
|
|
11
|
-
User,
|
|
1
|
+
const { sequelize } = require('../config/database');
|
|
2
|
+
const User = require('./User');
|
|
3
|
+
|
|
4
|
+
// Define associations here if you have multiple models
|
|
5
|
+
// Example:
|
|
6
|
+
// User.hasMany(Post);
|
|
7
|
+
// Post.belongsTo(User);
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
sequelize,
|
|
11
|
+
User,
|
|
12
12
|
};
|
|
@@ -1,14 +1,223 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
const router = express.Router();
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const authController = require('../controllers/authController');
|
|
3
|
+
const { validateLogin, validateRegister, validate, forgotPasswordSchema, resetPasswordSchema } = require('../middleware/validation');
|
|
4
|
+
const { authenticateToken } = require('../middleware/auth');
|
|
5
|
+
|
|
6
|
+
const router = express.Router();
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @swagger
|
|
10
|
+
* /auth/register:
|
|
11
|
+
* post:
|
|
12
|
+
* summary: Register a new user
|
|
13
|
+
* tags: [Authentication]
|
|
14
|
+
* requestBody:
|
|
15
|
+
* required: true
|
|
16
|
+
* content:
|
|
17
|
+
* application/json:
|
|
18
|
+
* schema:
|
|
19
|
+
* type: object
|
|
20
|
+
* required: [username, email, password]
|
|
21
|
+
* properties:
|
|
22
|
+
* username:
|
|
23
|
+
* type: string
|
|
24
|
+
* minLength: 3
|
|
25
|
+
* maxLength: 50
|
|
26
|
+
* description: Display name (3-50 characters)
|
|
27
|
+
* example: johndoe
|
|
28
|
+
* email:
|
|
29
|
+
* type: string
|
|
30
|
+
* format: email
|
|
31
|
+
* description: Valid email address
|
|
32
|
+
* example: john@example.com
|
|
33
|
+
* password:
|
|
34
|
+
* type: string
|
|
35
|
+
* minLength: 8
|
|
36
|
+
* description: "Must contain at least one uppercase letter, one lowercase letter, and one number"
|
|
37
|
+
* example: Secret123
|
|
38
|
+
* example:
|
|
39
|
+
* username: johndoe
|
|
40
|
+
* email: john@example.com
|
|
41
|
+
* password: Secret123
|
|
42
|
+
* responses:
|
|
43
|
+
* 201:
|
|
44
|
+
* description: User registered successfully
|
|
45
|
+
* content:
|
|
46
|
+
* application/json:
|
|
47
|
+
* schema:
|
|
48
|
+
* type: object
|
|
49
|
+
* properties:
|
|
50
|
+
* success:
|
|
51
|
+
* type: boolean
|
|
52
|
+
* example: true
|
|
53
|
+
* data:
|
|
54
|
+
* type: object
|
|
55
|
+
* properties:
|
|
56
|
+
* message:
|
|
57
|
+
* type: string
|
|
58
|
+
* user:
|
|
59
|
+
* type: object
|
|
60
|
+
* properties:
|
|
61
|
+
* id:
|
|
62
|
+
* type: string
|
|
63
|
+
* username:
|
|
64
|
+
* type: string
|
|
65
|
+
* email:
|
|
66
|
+
* type: string
|
|
67
|
+
* accessToken:
|
|
68
|
+
* type: string
|
|
69
|
+
* refreshToken:
|
|
70
|
+
* type: string
|
|
71
|
+
* 400:
|
|
72
|
+
* description: Validation error (weak password, invalid email, etc.)
|
|
73
|
+
* 409:
|
|
74
|
+
* description: User already exists
|
|
75
|
+
*/
|
|
76
|
+
router.post('/register', validateRegister, authController.register);
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @swagger
|
|
80
|
+
* /auth/login:
|
|
81
|
+
* post:
|
|
82
|
+
* summary: Login user
|
|
83
|
+
* tags: [Authentication]
|
|
84
|
+
* requestBody:
|
|
85
|
+
* required: true
|
|
86
|
+
* content:
|
|
87
|
+
* application/json:
|
|
88
|
+
* schema:
|
|
89
|
+
* type: object
|
|
90
|
+
* required: [email, password]
|
|
91
|
+
* properties:
|
|
92
|
+
* email:
|
|
93
|
+
* type: string
|
|
94
|
+
* format: email
|
|
95
|
+
* example: john@example.com
|
|
96
|
+
* password:
|
|
97
|
+
* type: string
|
|
98
|
+
* example: Secret123
|
|
99
|
+
* example:
|
|
100
|
+
* email: john@example.com
|
|
101
|
+
* password: Secret123
|
|
102
|
+
* responses:
|
|
103
|
+
* 200:
|
|
104
|
+
* description: Login successful
|
|
105
|
+
* content:
|
|
106
|
+
* application/json:
|
|
107
|
+
* schema:
|
|
108
|
+
* type: object
|
|
109
|
+
* properties:
|
|
110
|
+
* success:
|
|
111
|
+
* type: boolean
|
|
112
|
+
* example: true
|
|
113
|
+
* data:
|
|
114
|
+
* type: object
|
|
115
|
+
* properties:
|
|
116
|
+
* message:
|
|
117
|
+
* type: string
|
|
118
|
+
* user:
|
|
119
|
+
* type: object
|
|
120
|
+
* accessToken:
|
|
121
|
+
* type: string
|
|
122
|
+
* refreshToken:
|
|
123
|
+
* type: string
|
|
124
|
+
* 401:
|
|
125
|
+
* description: Invalid credentials
|
|
126
|
+
*/
|
|
127
|
+
router.post('/login', validateLogin, authController.login);
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @swagger
|
|
131
|
+
* /auth/refresh:
|
|
132
|
+
* post:
|
|
133
|
+
* summary: Refresh access token
|
|
134
|
+
* tags: [Authentication]
|
|
135
|
+
* requestBody:
|
|
136
|
+
* required: true
|
|
137
|
+
* content:
|
|
138
|
+
* application/json:
|
|
139
|
+
* schema:
|
|
140
|
+
* type: object
|
|
141
|
+
* required: [refreshToken]
|
|
142
|
+
* properties:
|
|
143
|
+
* refreshToken:
|
|
144
|
+
* type: string
|
|
145
|
+
* description: The refresh token received from login or register
|
|
146
|
+
* example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
147
|
+
* responses:
|
|
148
|
+
* 200:
|
|
149
|
+
* description: Token refreshed
|
|
150
|
+
* 401:
|
|
151
|
+
* description: Invalid refresh token
|
|
152
|
+
*/
|
|
153
|
+
router.post('/refresh', authController.refreshToken);
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @swagger
|
|
157
|
+
* /auth/logout:
|
|
158
|
+
* post:
|
|
159
|
+
* summary: Logout user
|
|
160
|
+
* tags: [Authentication]
|
|
161
|
+
* security:
|
|
162
|
+
* - bearerAuth: []
|
|
163
|
+
* responses:
|
|
164
|
+
* 200:
|
|
165
|
+
* description: Logout successful
|
|
166
|
+
*/
|
|
167
|
+
router.post('/logout', authenticateToken, authController.logout);
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* @swagger
|
|
171
|
+
* /auth/forgot-password:
|
|
172
|
+
* post:
|
|
173
|
+
* summary: Request password reset
|
|
174
|
+
* tags: [Authentication]
|
|
175
|
+
* requestBody:
|
|
176
|
+
* required: true
|
|
177
|
+
* content:
|
|
178
|
+
* application/json:
|
|
179
|
+
* schema:
|
|
180
|
+
* type: object
|
|
181
|
+
* required: [email]
|
|
182
|
+
* properties:
|
|
183
|
+
* email:
|
|
184
|
+
* type: string
|
|
185
|
+
* format: email
|
|
186
|
+
* example: john@example.com
|
|
187
|
+
* responses:
|
|
188
|
+
* 200:
|
|
189
|
+
* description: Reset link sent (if account exists)
|
|
190
|
+
*/
|
|
191
|
+
router.post('/forgot-password', validate({ body: forgotPasswordSchema }), authController.forgotPassword);
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @swagger
|
|
195
|
+
* /auth/reset-password:
|
|
196
|
+
* post:
|
|
197
|
+
* summary: Reset password with token
|
|
198
|
+
* tags: [Authentication]
|
|
199
|
+
* requestBody:
|
|
200
|
+
* required: true
|
|
201
|
+
* content:
|
|
202
|
+
* application/json:
|
|
203
|
+
* schema:
|
|
204
|
+
* type: object
|
|
205
|
+
* required: [token, password]
|
|
206
|
+
* properties:
|
|
207
|
+
* token:
|
|
208
|
+
* type: string
|
|
209
|
+
* description: The reset token from the password reset email
|
|
210
|
+
* password:
|
|
211
|
+
* type: string
|
|
212
|
+
* minLength: 8
|
|
213
|
+
* description: "Must contain at least one uppercase letter, one lowercase letter, and one number"
|
|
214
|
+
* example: NewSecret123
|
|
215
|
+
* responses:
|
|
216
|
+
* 200:
|
|
217
|
+
* description: Password reset successful
|
|
218
|
+
* 400:
|
|
219
|
+
* description: Invalid or expired reset token
|
|
220
|
+
*/
|
|
221
|
+
router.post('/reset-password', validate({ body: resetPasswordSchema }), authController.resetPassword);
|
|
222
|
+
|
|
14
223
|
module.exports = router;
|
|
@@ -1,13 +1,101 @@
|
|
|
1
|
-
const express = require('express');
|
|
2
|
-
const exampleController = require('../controllers/exampleController');
|
|
3
|
-
|
|
4
|
-
const router = express.Router();
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const exampleController = require('../controllers/exampleController');
|
|
3
|
+
|
|
4
|
+
const router = express.Router();
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @swagger
|
|
8
|
+
* /examples:
|
|
9
|
+
* get:
|
|
10
|
+
* summary: Get all examples
|
|
11
|
+
* tags: [Examples]
|
|
12
|
+
* parameters:
|
|
13
|
+
* - in: query
|
|
14
|
+
* name: page
|
|
15
|
+
* schema:
|
|
16
|
+
* type: integer
|
|
17
|
+
* default: 1
|
|
18
|
+
* description: Page number
|
|
19
|
+
* - in: query
|
|
20
|
+
* name: limit
|
|
21
|
+
* schema:
|
|
22
|
+
* type: integer
|
|
23
|
+
* default: 10
|
|
24
|
+
* description: Items per page (max 100)
|
|
25
|
+
* responses:
|
|
26
|
+
* 200:
|
|
27
|
+
* description: Examples retrieved
|
|
28
|
+
* post:
|
|
29
|
+
* summary: Create new example
|
|
30
|
+
* tags: [Examples]
|
|
31
|
+
* requestBody:
|
|
32
|
+
* required: true
|
|
33
|
+
* content:
|
|
34
|
+
* application/json:
|
|
35
|
+
* schema:
|
|
36
|
+
* type: object
|
|
37
|
+
* required: [title, description]
|
|
38
|
+
* properties:
|
|
39
|
+
* title:
|
|
40
|
+
* type: string
|
|
41
|
+
* example: My First Example
|
|
42
|
+
* description:
|
|
43
|
+
* type: string
|
|
44
|
+
* example: A description of the example item
|
|
45
|
+
* example:
|
|
46
|
+
* title: My First Example
|
|
47
|
+
* description: A description of the example item
|
|
48
|
+
* responses:
|
|
49
|
+
* 201:
|
|
50
|
+
* description: Example created
|
|
51
|
+
*/
|
|
52
|
+
router.get('/', exampleController.getAllExamples);
|
|
53
|
+
router.post('/', exampleController.createExample);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @swagger
|
|
57
|
+
* /examples/{id}:
|
|
58
|
+
* get:
|
|
59
|
+
* summary: Get example by ID
|
|
60
|
+
* tags: [Examples]
|
|
61
|
+
* parameters:
|
|
62
|
+
* - in: path
|
|
63
|
+
* name: id
|
|
64
|
+
* required: true
|
|
65
|
+
* schema:
|
|
66
|
+
* type: string
|
|
67
|
+
* responses:
|
|
68
|
+
* 200:
|
|
69
|
+
* description: Example retrieved
|
|
70
|
+
* 404:
|
|
71
|
+
* description: Example not found
|
|
72
|
+
* put:
|
|
73
|
+
* summary: Update example
|
|
74
|
+
* tags: [Examples]
|
|
75
|
+
* parameters:
|
|
76
|
+
* - in: path
|
|
77
|
+
* name: id
|
|
78
|
+
* required: true
|
|
79
|
+
* schema:
|
|
80
|
+
* type: string
|
|
81
|
+
* responses:
|
|
82
|
+
* 200:
|
|
83
|
+
* description: Example updated
|
|
84
|
+
* delete:
|
|
85
|
+
* summary: Delete example
|
|
86
|
+
* tags: [Examples]
|
|
87
|
+
* parameters:
|
|
88
|
+
* - in: path
|
|
89
|
+
* name: id
|
|
90
|
+
* required: true
|
|
91
|
+
* schema:
|
|
92
|
+
* type: string
|
|
93
|
+
* responses:
|
|
94
|
+
* 200:
|
|
95
|
+
* description: Example deleted
|
|
96
|
+
*/
|
|
97
|
+
router.get('/:id', exampleController.getExampleById);
|
|
98
|
+
router.put('/:id', exampleController.updateExample);
|
|
99
|
+
router.delete('/:id', exampleController.deleteExample);
|
|
100
|
+
|
|
13
101
|
module.exports = router;
|
|
@@ -1,24 +1,34 @@
|
|
|
1
|
-
const express = require('express')
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
const express = require('express');
|
|
2
|
+
<% if (hasAuth) { %>const authRoutes = require('./authRoutes');
|
|
3
|
+
const userRoutes = require('./userRoutes');
|
|
4
|
+
<% } else { %>const exampleRoutes = require('./exampleRoutes');
|
|
5
|
+
<% } %>
|
|
6
|
+
|
|
7
|
+
const router = express.Router();
|
|
8
|
+
|
|
9
|
+
<% if (hasAuth) { %>router.use('/auth', authRoutes);
|
|
10
|
+
router.use('/users', userRoutes);
|
|
11
|
+
<% } else { %>router.use('/examples', exampleRoutes);
|
|
12
|
+
<% } %>
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @swagger
|
|
16
|
+
* /api:
|
|
17
|
+
* get:
|
|
18
|
+
* summary: API root
|
|
19
|
+
* responses:
|
|
20
|
+
* 200:
|
|
21
|
+
* description: API information
|
|
22
|
+
*/
|
|
23
|
+
router.get('/', (req, res) => {
|
|
24
|
+
res.json({
|
|
25
|
+
success: true,
|
|
26
|
+
data: {
|
|
27
|
+
message: 'Welcome to the API',
|
|
28
|
+
version: '1.0.0',<% if (hasSwagger) { %>
|
|
29
|
+
documentation: '/api-docs',<% } %>
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
module.exports = router;
|