create-sip 1.2.1 → 1.3.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/README.md +0 -173
- package/create-sip.js +1 -1
- package/expressapi/.env.example +10 -0
- package/expressapi/.env.test +7 -0
- package/expressapi/README.md +24 -2
- package/expressapi/app/app.js +17 -0
- package/expressapi/app/controllers/authController.js +9 -11
- package/expressapi/app/controllers/userController.js +36 -1
- package/expressapi/app/database/database.js +14 -14
- package/expressapi/app/index.js +4 -18
- package/expressapi/app/{middlewares → middleware}/authjwt.js +3 -4
- package/expressapi/app/routes/api.js +4 -2
- package/expressapi/database/migrations/2025_10_08_075231_user.js +34 -0
- package/expressapi/docs/dev_doc.md +13 -1
- package/expressapi/docs/user_doc.md +157 -13
- package/expressapi/op +86 -54
- package/expressapi/package-lock.json +5698 -0
- package/expressapi/package.json +3 -1
- package/expressapi/test/{test.js → user.spec.js} +10 -10
- package/manager.js +3 -1
- package/package.json +1 -1
- package/expressapi/config/default.json.example +0 -15
|
@@ -2,23 +2,45 @@
|
|
|
2
2
|
|
|
3
3
|
## Install dependencies
|
|
4
4
|
|
|
5
|
+
Dependencies must be installed before use.
|
|
6
|
+
|
|
5
7
|
```cmd
|
|
6
8
|
npm install
|
|
7
9
|
```
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
Or use your favorite package manager.
|
|
12
|
+
|
|
13
|
+
## Generate config file
|
|
14
|
+
|
|
15
|
+
The settings are located in a file called:
|
|
16
|
+
|
|
17
|
+
* .env
|
|
18
|
+
|
|
19
|
+
To generate the .env file:
|
|
10
20
|
|
|
11
|
-
|
|
21
|
+
```cmd
|
|
22
|
+
node op conf:generate
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Test configurations file generate
|
|
26
|
+
|
|
27
|
+
```cmd
|
|
28
|
+
node op testconf:generate
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Result: .env.test file.
|
|
12
32
|
|
|
13
33
|
## App key generation
|
|
14
34
|
|
|
35
|
+
Te generate the application key:
|
|
36
|
+
|
|
15
37
|
```cmd
|
|
16
38
|
node op key:generate
|
|
17
39
|
```
|
|
18
40
|
|
|
19
41
|
## Database setup
|
|
20
42
|
|
|
21
|
-
Edit the
|
|
43
|
+
Edit the .env file.
|
|
22
44
|
|
|
23
45
|
## Endpoints
|
|
24
46
|
|
|
@@ -29,6 +51,8 @@ All endpoint have a /api prefix.
|
|
|
29
51
|
| /register | POST | no | create user |
|
|
30
52
|
| /login | POST | no | login |
|
|
31
53
|
| /users | GET | yes | read users |
|
|
54
|
+
| /users/:id | GET | yes | read user |
|
|
55
|
+
| /users/:id/password | PUT | yes | change password |
|
|
32
56
|
|
|
33
57
|
## The register endpoint
|
|
34
58
|
|
|
@@ -54,29 +78,37 @@ You receive the bearear token with accessToken key.
|
|
|
54
78
|
|
|
55
79
|
## The users endpoint
|
|
56
80
|
|
|
57
|
-
|
|
81
|
+
To query users or user, send the bearer token to endpoint.
|
|
58
82
|
|
|
59
83
|
## Model and controller generation
|
|
60
84
|
|
|
85
|
+
Use the following instructions to generate models and controllers:
|
|
86
|
+
|
|
61
87
|
```cmd
|
|
62
|
-
node op
|
|
63
|
-
node op
|
|
88
|
+
node op make:model thing
|
|
89
|
+
node op make:controller thing
|
|
64
90
|
```
|
|
65
91
|
|
|
66
92
|
## Key generation
|
|
67
93
|
|
|
94
|
+
You can generate the application key with the following command:
|
|
95
|
+
|
|
68
96
|
```cmd
|
|
69
97
|
node op key:generate
|
|
70
98
|
```
|
|
71
99
|
|
|
72
100
|
## Generate admin user
|
|
73
101
|
|
|
102
|
+
You can create an admin user if it does not already exist in the database:
|
|
103
|
+
|
|
74
104
|
```cmd
|
|
75
105
|
node op admin:generate
|
|
76
106
|
```
|
|
77
107
|
|
|
78
108
|
## Database import
|
|
79
109
|
|
|
110
|
+
It is possible to import data from JSON and CSV files.
|
|
111
|
+
|
|
80
112
|
```cmd
|
|
81
113
|
node op db:import thing things.json
|
|
82
114
|
node op db:import thing things.csv
|
|
@@ -85,13 +117,125 @@ node op db:import thing things.csv ";"
|
|
|
85
117
|
node op db:import thing things.csv :
|
|
86
118
|
```
|
|
87
119
|
|
|
88
|
-
|
|
120
|
+
The last option is the separator.
|
|
121
|
+
|
|
122
|
+
For example JSON file:
|
|
123
|
+
|
|
124
|
+
employees.json:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
[
|
|
128
|
+
{ "id": 1, "name": "Tom Large" },
|
|
129
|
+
{ "id": 2, "name": "Jack Small" }
|
|
130
|
+
]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The default separator is comma.
|
|
134
|
+
|
|
135
|
+
```cmd
|
|
136
|
+
node op db:import employee employees.json
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
For example CSV file:
|
|
140
|
+
|
|
141
|
+
employees.csv:
|
|
142
|
+
|
|
143
|
+
```csv
|
|
144
|
+
id,name
|
|
145
|
+
1,Joe Kitin
|
|
146
|
+
2,Peter Fall
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
If you have colon separator, use sep parameter.
|
|
150
|
+
|
|
151
|
+
```csv
|
|
152
|
+
id:name
|
|
153
|
+
1:Joe Kitin
|
|
154
|
+
2:Peter Fall
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```cmd
|
|
158
|
+
node op db:import employee employees.csv --sep :
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
If the file has semicolon separator, use sep parameter, for example:
|
|
162
|
+
|
|
163
|
+
```csv
|
|
164
|
+
id;name
|
|
165
|
+
1;Joe Kitin
|
|
166
|
+
2;Peter Fall
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Use next command:
|
|
89
170
|
|
|
90
171
|
```cmd
|
|
91
|
-
node op
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
172
|
+
node op db:import employee employees.csv --sep ";"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Database
|
|
176
|
+
|
|
177
|
+
### Database synchronization
|
|
178
|
+
|
|
179
|
+
Models and database tables can be synchronized, but this can be dangerous.
|
|
180
|
+
|
|
181
|
+
Database synchronization can be set up in the app/models/modrels.js file. Default values are:
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
{ alter: true }
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This preserves the data and existing structure.
|
|
188
|
+
|
|
189
|
+
Possible values:
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
{ force: true }
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The latter deletes the contents of the database table!
|
|
196
|
+
|
|
197
|
+
If the value is false, there is no synchronization in either case.
|
|
198
|
+
|
|
199
|
+
### Migration
|
|
200
|
+
|
|
201
|
+
Generate a migration:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
node op make/migration thing
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Run all migration:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
node op migration:run
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Run a migration:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
node op migration:run <migration_name>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Rollback a migration:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
node op migration:rollback
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Rollback two migrations:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
node op migration:rollback 2
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Reset the database:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
node op migration:reset
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Reset the database and run all migrations:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
node op migration:fresh
|
|
97
241
|
```
|
package/expressapi/op
CHANGED
|
@@ -8,11 +8,12 @@ import bcrypt from 'bcryptjs';
|
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import { read } from 'read';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
yargs(hideBin(process.argv))
|
|
12
12
|
.version()
|
|
13
|
+
.strict()
|
|
13
14
|
.usage('Használat: node op <command> [name]')
|
|
14
15
|
.help()
|
|
15
|
-
.demandCommand(
|
|
16
|
+
.demandCommand(2, 'Not enough arguments!')
|
|
16
17
|
.command('make:model <name>',
|
|
17
18
|
'Generates a new Sequelize model',
|
|
18
19
|
(yargs) => {
|
|
@@ -51,7 +52,7 @@ const { argv } = yargs(hideBin(process.argv))
|
|
|
51
52
|
}
|
|
52
53
|
)
|
|
53
54
|
.command('conf:generate',
|
|
54
|
-
'
|
|
55
|
+
'Generate a new config file: .env',
|
|
55
56
|
(yargs) => {
|
|
56
57
|
return yargs
|
|
57
58
|
},
|
|
@@ -59,8 +60,17 @@ const { argv } = yargs(hideBin(process.argv))
|
|
|
59
60
|
startGenerateConf();
|
|
60
61
|
}
|
|
61
62
|
)
|
|
63
|
+
.command('testconf:generate',
|
|
64
|
+
'Generate a new config file: .env.test',
|
|
65
|
+
(yargs) => {
|
|
66
|
+
return yargs
|
|
67
|
+
},
|
|
68
|
+
async (argv) => {
|
|
69
|
+
startGenerateTestConf();
|
|
70
|
+
}
|
|
71
|
+
)
|
|
62
72
|
.command('admin:generate',
|
|
63
|
-
'Generates a new admin user',
|
|
73
|
+
'Generates a new admin user in database table: users',
|
|
64
74
|
(yargs) => {
|
|
65
75
|
return yargs
|
|
66
76
|
},
|
|
@@ -240,42 +250,64 @@ function capitalizeFirstLetter(word) {
|
|
|
240
250
|
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
241
251
|
}
|
|
242
252
|
|
|
243
|
-
function startGenerateKey() {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
253
|
+
async function startGenerateKey() {
|
|
254
|
+
try {
|
|
255
|
+
const envFile = '.env'
|
|
256
|
+
let content = await fse.readFile(envFile, 'utf8')
|
|
257
|
+
const key = generateApiKey({method: 'bytes', length: 32})
|
|
258
|
+
|
|
259
|
+
const regex = /^APP_KEY *=.*$/m
|
|
260
|
+
if(regex.test(content)) {
|
|
261
|
+
content = content.replace(regex, `APP_KEY=${key}`)
|
|
262
|
+
}else {
|
|
263
|
+
if(content.trim() !== '') {
|
|
264
|
+
content += `\nAPP_KEY=${key}\n`
|
|
265
|
+
}else {
|
|
266
|
+
content = `APP_KEY=${key}\n`
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
fse.writeFile(envFile, content, 'utf8')
|
|
270
|
+
} catch (error) {
|
|
271
|
+
console.error(error)
|
|
272
|
+
}
|
|
255
273
|
}
|
|
256
274
|
|
|
257
275
|
async function startGenerateConf() {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
276
|
+
const content = `
|
|
277
|
+
APP_PORT=8000
|
|
278
|
+
APP_KEY=
|
|
279
|
+
APP_LOG=console.log
|
|
280
|
+
|
|
281
|
+
DB_DIALECT=sqlite
|
|
282
|
+
DB_HOST=127.0.0.1
|
|
283
|
+
DB_NAME=
|
|
284
|
+
DB_USER=
|
|
285
|
+
DB_PASS=
|
|
286
|
+
DB_PATH=:memory:
|
|
287
|
+
`
|
|
288
|
+
const destinationFileName = '.env'
|
|
289
|
+
if(await startCheckIfFileExists(destinationFileName)) {
|
|
290
|
+
process.exit(1);
|
|
265
291
|
}
|
|
266
|
-
|
|
292
|
+
|
|
293
|
+
await fse.writeFile(destinationFileName, content, 'utf8')
|
|
267
294
|
}
|
|
268
295
|
|
|
269
|
-
async function
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
296
|
+
async function startGenerateTestConf() {
|
|
297
|
+
const content = `
|
|
298
|
+
APP_PORT=8000
|
|
299
|
+
APP_KEY=my_secret_key
|
|
300
|
+
APP_LOG=console.log
|
|
301
|
+
|
|
302
|
+
DB_DIALECT=sqlite
|
|
303
|
+
DB_PATH=:memory:
|
|
304
|
+
`
|
|
305
|
+
const destinationFileName = '.env.test'
|
|
306
|
+
if(await startCheckIfFileExists(destinationFileName)) {
|
|
307
|
+
process.exit(1);
|
|
278
308
|
}
|
|
309
|
+
|
|
310
|
+
await fse.writeFile(destinationFileName, content, 'utf8')
|
|
279
311
|
}
|
|
280
312
|
|
|
281
313
|
async function inputPassword() {
|
|
@@ -288,33 +320,33 @@ async function inputPassword() {
|
|
|
288
320
|
}
|
|
289
321
|
|
|
290
322
|
async function startGenerateAdmin() {
|
|
291
|
-
console.log('Generate admin...')
|
|
292
323
|
try {
|
|
293
|
-
const
|
|
294
|
-
|
|
324
|
+
const { default: User } = await import('./app/models/user.js')
|
|
325
|
+
await User.sync()
|
|
326
|
+
|
|
327
|
+
await import('dotenv').then((dotenv) => dotenv.config())
|
|
328
|
+
const isMemoryDb = process.env.DB_PATH === ':memory:';
|
|
295
329
|
if(isMemoryDb) {
|
|
296
330
|
console.log('Admin cannot be created in memory db!')
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
await User.sync()
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
300
333
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
const password = await inputPassword()
|
|
307
|
-
const hashedPassword = await bcrypt.hash(password, 10);
|
|
308
|
-
await User.create({
|
|
309
|
-
name: 'admin',
|
|
310
|
-
email: 'admin',
|
|
311
|
-
password: hashedPassword
|
|
312
|
-
})
|
|
313
|
-
console.log('Admin created!')
|
|
334
|
+
const isUserExist = await User.findOne({ where: { name: 'admin' } })
|
|
335
|
+
if (isUserExist) {
|
|
336
|
+
console.log('Admin already exists!')
|
|
337
|
+
return;
|
|
314
338
|
}
|
|
315
|
-
|
|
339
|
+
const password = await inputPassword()
|
|
340
|
+
const hashedPassword = await bcrypt.hash(password, 10);
|
|
341
|
+
await User.create({
|
|
342
|
+
name: 'admin',
|
|
343
|
+
email: 'admin',
|
|
344
|
+
password: hashedPassword
|
|
345
|
+
})
|
|
346
|
+
console.log('Admin created!')
|
|
347
|
+
} catch (error) {
|
|
316
348
|
console.error('Error creating admin!')
|
|
317
|
-
console.error(
|
|
349
|
+
console.error(error)
|
|
318
350
|
}
|
|
319
351
|
}
|
|
320
352
|
|