@seip/blue-bird 0.2.0 → 0.2.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.
- package/.env_example +11 -11
- package/LICENSE +21 -21
- package/README.md +80 -80
- package/backend/index.js +12 -12
- package/backend/routes/app.js +52 -40
- package/core/app.js +182 -182
- package/core/auth.js +69 -69
- package/core/cli/component.js +42 -42
- package/core/cli/init.js +117 -116
- package/core/cli/react.js +408 -393
- package/core/cli/route.js +42 -42
- package/core/config.js +41 -41
- package/core/logger.js +80 -80
- package/core/middleware.js +27 -27
- package/core/router.js +134 -134
- package/core/template.js +283 -220
- package/core/upload.js +76 -76
- package/core/validate.js +291 -291
- package/frontend/index.html +20 -0
- package/package.json +40 -43
package/core/app.js
CHANGED
|
@@ -1,182 +1,182 @@
|
|
|
1
|
-
import express from "express"
|
|
2
|
-
import cors from "cors"
|
|
3
|
-
import path from "path"
|
|
4
|
-
import chalk from "chalk"
|
|
5
|
-
import cookieParser from "cookie-parser"
|
|
6
|
-
import Config from "./config.js"
|
|
7
|
-
import Logger from "./logger.js"
|
|
8
|
-
|
|
9
|
-
const __dirname = Config.dirname()
|
|
10
|
-
const props = Config.props()
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Main Application class to manage Express server, routes, and middlewares.
|
|
14
|
-
*/
|
|
15
|
-
class App {
|
|
16
|
-
/**
|
|
17
|
-
* Initializes the App instance with the provided options.
|
|
18
|
-
* @param {Object} [options] - Configuration options for the application.
|
|
19
|
-
* @param {Array<{path: string, router: import('express').Router}>} [options.routes=[]] - Array of route objects containing path and router components.
|
|
20
|
-
* @param {Object} [options.cors={}] - CORS configuration options.
|
|
21
|
-
* @param {Array<Function>} [options.middlewares=[]] - Array of middleware functions to be applied.
|
|
22
|
-
* @param {number|string} [options.port=3000] - Server port.
|
|
23
|
-
* @param {string} [options.host="http://localhost"] - Server host URL.
|
|
24
|
-
* @param {boolean} [options.logger=true] - Whether to enable the request logger.
|
|
25
|
-
* @param {boolean} [options.notFound=true] - Whether to enable the default 404 handler.
|
|
26
|
-
* @param {boolean} [options.json=true] - Whether to enable JSON body parsing.
|
|
27
|
-
* @param {boolean} [options.urlencoded=true] - Whether to enable URL-encoded body parsing.
|
|
28
|
-
* @param {Object} [options.static={path: null, options: {}}] - Static file configuration.
|
|
29
|
-
* @param {boolean} [options.cookieParser=true] - Whether to enable cookie parsing.
|
|
30
|
-
* @example
|
|
31
|
-
* const app = new App({
|
|
32
|
-
* routes: [],
|
|
33
|
-
* cors: {},
|
|
34
|
-
* middlewares: [],
|
|
35
|
-
* port: 3000,
|
|
36
|
-
* host: "http://localhost",
|
|
37
|
-
* logger: true,
|
|
38
|
-
* notFound: true,
|
|
39
|
-
* json: true,
|
|
40
|
-
* urlencoded: true,
|
|
41
|
-
* static: {
|
|
42
|
-
* path: "public",
|
|
43
|
-
* options: {}
|
|
44
|
-
* },
|
|
45
|
-
* cookieParser: true,
|
|
46
|
-
* });
|
|
47
|
-
*/
|
|
48
|
-
constructor(options = {
|
|
49
|
-
routes: [],
|
|
50
|
-
cors: {},
|
|
51
|
-
middlewares: [],
|
|
52
|
-
port: null,
|
|
53
|
-
host: null,
|
|
54
|
-
logger: true,
|
|
55
|
-
notFound: true,
|
|
56
|
-
json: true,
|
|
57
|
-
urlencoded: true,
|
|
58
|
-
static: {
|
|
59
|
-
path: null,
|
|
60
|
-
options: {}
|
|
61
|
-
},
|
|
62
|
-
cookieParser: true,
|
|
63
|
-
|
|
64
|
-
}) {
|
|
65
|
-
this.app = express()
|
|
66
|
-
this.routes = options.routes || []
|
|
67
|
-
this.cors = options.cors || {}
|
|
68
|
-
this.middlewares = options.middlewares || []
|
|
69
|
-
this.port = options.port || props.port
|
|
70
|
-
this.host = options.host || props.host
|
|
71
|
-
this.logger = options.logger || true
|
|
72
|
-
this.notFound = options.notFound || true
|
|
73
|
-
this.json = options.json || true
|
|
74
|
-
this.urlencoded = options.urlencoded || true
|
|
75
|
-
this.static = options.static || props.static
|
|
76
|
-
this.cookieParser = options.cookieParser || true
|
|
77
|
-
this.dispatch()
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Registers a custom middleware or module in the Express application.
|
|
83
|
-
* @param {Function|import('express').Router} record - The middleware function or Express router to register.
|
|
84
|
-
* @example
|
|
85
|
-
* app.use((req, res, next) => {
|
|
86
|
-
* console.log("Middleware");
|
|
87
|
-
* next();
|
|
88
|
-
* });
|
|
89
|
-
*/
|
|
90
|
-
use(record) {
|
|
91
|
-
this.app.use(record)
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Sets a configuration value in the Express application.
|
|
95
|
-
* @param {string} key - The configuration key.
|
|
96
|
-
* @param {*} value - The value to set for the configuration key.
|
|
97
|
-
* @example
|
|
98
|
-
* app.set("port", 3000);
|
|
99
|
-
*/
|
|
100
|
-
set(key, value) {
|
|
101
|
-
this.app.set(key, value)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Bootstraps the application by configuring global middlewares and routes.
|
|
106
|
-
* Sets up JSON parsing, URL encoding, CORS, and custom middlewares.
|
|
107
|
-
*/
|
|
108
|
-
dispatch() {
|
|
109
|
-
if (this.json) this.app.use(express.json())
|
|
110
|
-
if (this.urlencoded) this.app.use(express.urlencoded({ extended: true }))
|
|
111
|
-
if (this.cookieParser) this.app.use(cookieParser())
|
|
112
|
-
if (this.static.path) this.app.use(express.static(path.join(__dirname, this.static.path), this.static.options))
|
|
113
|
-
this.app.use(cors(this.cors))
|
|
114
|
-
this.middlewares.map(middleware => {
|
|
115
|
-
this.app.use(middleware)
|
|
116
|
-
})
|
|
117
|
-
if (this.logger) this.middlewareLogger()
|
|
118
|
-
this.app.use((req, res, next) => {
|
|
119
|
-
res.setHeader('X-Powered-By', 'Blue Bird');
|
|
120
|
-
next();
|
|
121
|
-
});
|
|
122
|
-
this.dispatchRoutes()
|
|
123
|
-
|
|
124
|
-
if (this.notFound) this.notFoundDefault()
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Middleware that logs incoming HTTP requests to the console and to a log file.
|
|
130
|
-
*/
|
|
131
|
-
middlewareLogger() {
|
|
132
|
-
this.app.use((req, res, next) => {
|
|
133
|
-
const method = req.method
|
|
134
|
-
const url = req.url
|
|
135
|
-
const params = Object.keys(req.params).length > 0 ? ` ${JSON.stringify(req.params)}` : ""
|
|
136
|
-
const ip = req.ip
|
|
137
|
-
const now = new Date().toISOString()
|
|
138
|
-
const time = `${now.split("T")[0]} ${now.split("T")[1].split(".")[0]}`
|
|
139
|
-
let message = ` ${time} -${ip} -[${method}] ${url} ${params}`
|
|
140
|
-
const logger = new Logger()
|
|
141
|
-
logger.info(message)
|
|
142
|
-
if (props.debug) {
|
|
143
|
-
message = `${chalk.bold.green(time)} - ${chalk.bold.cyan(ip)} -[${chalk.bold.red(method)}] ${chalk.bold.blue(url)} ${chalk.bold.yellow(params)}`
|
|
144
|
-
console.log(message)
|
|
145
|
-
}
|
|
146
|
-
next()
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Iterates through the stored routes and attaches them to the Express application instance.
|
|
152
|
-
*/
|
|
153
|
-
dispatchRoutes() {
|
|
154
|
-
this.routes.map(route => {
|
|
155
|
-
this.app.use(route.path, route.router)
|
|
156
|
-
})
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Default 404 handler for unmatched routes.
|
|
160
|
-
* Returns a JSON response with a "Not Found" message.
|
|
161
|
-
*/
|
|
162
|
-
notFoundDefault() {
|
|
163
|
-
this.app.use((req, res) => {
|
|
164
|
-
return res.status(404).json({ message: "Not Found" })
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Starts the HTTP server and begins listening for incoming connections.
|
|
169
|
-
*/
|
|
170
|
-
run() {
|
|
171
|
-
this.app.listen(this.port, () => {
|
|
172
|
-
console.log(
|
|
173
|
-
chalk.bold.blue('Blue Bird Server Online\n') +
|
|
174
|
-
chalk.bold.cyan('Host: ') + chalk.green(`${this.host}:${this.port}`) + '\n' +
|
|
175
|
-
chalk.gray('────────────────────────────────')
|
|
176
|
-
);
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export default App
|
|
182
|
-
|
|
1
|
+
import express from "express"
|
|
2
|
+
import cors from "cors"
|
|
3
|
+
import path from "path"
|
|
4
|
+
import chalk from "chalk"
|
|
5
|
+
import cookieParser from "cookie-parser"
|
|
6
|
+
import Config from "./config.js"
|
|
7
|
+
import Logger from "./logger.js"
|
|
8
|
+
|
|
9
|
+
const __dirname = Config.dirname()
|
|
10
|
+
const props = Config.props()
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Main Application class to manage Express server, routes, and middlewares.
|
|
14
|
+
*/
|
|
15
|
+
class App {
|
|
16
|
+
/**
|
|
17
|
+
* Initializes the App instance with the provided options.
|
|
18
|
+
* @param {Object} [options] - Configuration options for the application.
|
|
19
|
+
* @param {Array<{path: string, router: import('express').Router}>} [options.routes=[]] - Array of route objects containing path and router components.
|
|
20
|
+
* @param {Object} [options.cors={}] - CORS configuration options.
|
|
21
|
+
* @param {Array<Function>} [options.middlewares=[]] - Array of middleware functions to be applied.
|
|
22
|
+
* @param {number|string} [options.port=3000] - Server port.
|
|
23
|
+
* @param {string} [options.host="http://localhost"] - Server host URL.
|
|
24
|
+
* @param {boolean} [options.logger=true] - Whether to enable the request logger.
|
|
25
|
+
* @param {boolean} [options.notFound=true] - Whether to enable the default 404 handler.
|
|
26
|
+
* @param {boolean} [options.json=true] - Whether to enable JSON body parsing.
|
|
27
|
+
* @param {boolean} [options.urlencoded=true] - Whether to enable URL-encoded body parsing.
|
|
28
|
+
* @param {Object} [options.static={path: null, options: {}}] - Static file configuration.
|
|
29
|
+
* @param {boolean} [options.cookieParser=true] - Whether to enable cookie parsing.
|
|
30
|
+
* @example
|
|
31
|
+
* const app = new App({
|
|
32
|
+
* routes: [],
|
|
33
|
+
* cors: {},
|
|
34
|
+
* middlewares: [],
|
|
35
|
+
* port: 3000,
|
|
36
|
+
* host: "http://localhost",
|
|
37
|
+
* logger: true,
|
|
38
|
+
* notFound: true,
|
|
39
|
+
* json: true,
|
|
40
|
+
* urlencoded: true,
|
|
41
|
+
* static: {
|
|
42
|
+
* path: "public",
|
|
43
|
+
* options: {}
|
|
44
|
+
* },
|
|
45
|
+
* cookieParser: true,
|
|
46
|
+
* });
|
|
47
|
+
*/
|
|
48
|
+
constructor(options = {
|
|
49
|
+
routes: [],
|
|
50
|
+
cors: {},
|
|
51
|
+
middlewares: [],
|
|
52
|
+
port: null,
|
|
53
|
+
host: null,
|
|
54
|
+
logger: true,
|
|
55
|
+
notFound: true,
|
|
56
|
+
json: true,
|
|
57
|
+
urlencoded: true,
|
|
58
|
+
static: {
|
|
59
|
+
path: null,
|
|
60
|
+
options: {}
|
|
61
|
+
},
|
|
62
|
+
cookieParser: true,
|
|
63
|
+
|
|
64
|
+
}) {
|
|
65
|
+
this.app = express()
|
|
66
|
+
this.routes = options.routes || []
|
|
67
|
+
this.cors = options.cors || {}
|
|
68
|
+
this.middlewares = options.middlewares || []
|
|
69
|
+
this.port = options.port || props.port
|
|
70
|
+
this.host = options.host || props.host
|
|
71
|
+
this.logger = options.logger || true
|
|
72
|
+
this.notFound = options.notFound || true
|
|
73
|
+
this.json = options.json || true
|
|
74
|
+
this.urlencoded = options.urlencoded || true
|
|
75
|
+
this.static = options.static || props.static
|
|
76
|
+
this.cookieParser = options.cookieParser || true
|
|
77
|
+
this.dispatch()
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Registers a custom middleware or module in the Express application.
|
|
83
|
+
* @param {Function|import('express').Router} record - The middleware function or Express router to register.
|
|
84
|
+
* @example
|
|
85
|
+
* app.use((req, res, next) => {
|
|
86
|
+
* console.log("Middleware");
|
|
87
|
+
* next();
|
|
88
|
+
* });
|
|
89
|
+
*/
|
|
90
|
+
use(record) {
|
|
91
|
+
this.app.use(record)
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Sets a configuration value in the Express application.
|
|
95
|
+
* @param {string} key - The configuration key.
|
|
96
|
+
* @param {*} value - The value to set for the configuration key.
|
|
97
|
+
* @example
|
|
98
|
+
* app.set("port", 3000);
|
|
99
|
+
*/
|
|
100
|
+
set(key, value) {
|
|
101
|
+
this.app.set(key, value)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Bootstraps the application by configuring global middlewares and routes.
|
|
106
|
+
* Sets up JSON parsing, URL encoding, CORS, and custom middlewares.
|
|
107
|
+
*/
|
|
108
|
+
dispatch() {
|
|
109
|
+
if (this.json) this.app.use(express.json())
|
|
110
|
+
if (this.urlencoded) this.app.use(express.urlencoded({ extended: true }))
|
|
111
|
+
if (this.cookieParser) this.app.use(cookieParser())
|
|
112
|
+
if (this.static.path) this.app.use(express.static(path.join(__dirname, this.static.path), this.static.options))
|
|
113
|
+
this.app.use(cors(this.cors))
|
|
114
|
+
this.middlewares.map(middleware => {
|
|
115
|
+
this.app.use(middleware)
|
|
116
|
+
})
|
|
117
|
+
if (this.logger) this.middlewareLogger()
|
|
118
|
+
this.app.use((req, res, next) => {
|
|
119
|
+
res.setHeader('X-Powered-By', 'Blue Bird');
|
|
120
|
+
next();
|
|
121
|
+
});
|
|
122
|
+
this.dispatchRoutes()
|
|
123
|
+
|
|
124
|
+
if (this.notFound) this.notFoundDefault()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Middleware that logs incoming HTTP requests to the console and to a log file.
|
|
130
|
+
*/
|
|
131
|
+
middlewareLogger() {
|
|
132
|
+
this.app.use((req, res, next) => {
|
|
133
|
+
const method = req.method
|
|
134
|
+
const url = req.url
|
|
135
|
+
const params = Object.keys(req.params).length > 0 ? ` ${JSON.stringify(req.params)}` : ""
|
|
136
|
+
const ip = req.ip
|
|
137
|
+
const now = new Date().toISOString()
|
|
138
|
+
const time = `${now.split("T")[0]} ${now.split("T")[1].split(".")[0]}`
|
|
139
|
+
let message = ` ${time} -${ip} -[${method}] ${url} ${params}`
|
|
140
|
+
const logger = new Logger()
|
|
141
|
+
logger.info(message)
|
|
142
|
+
if (props.debug) {
|
|
143
|
+
message = `${chalk.bold.green(time)} - ${chalk.bold.cyan(ip)} -[${chalk.bold.red(method)}] ${chalk.bold.blue(url)} ${chalk.bold.yellow(params)}`
|
|
144
|
+
console.log(message)
|
|
145
|
+
}
|
|
146
|
+
next()
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Iterates through the stored routes and attaches them to the Express application instance.
|
|
152
|
+
*/
|
|
153
|
+
dispatchRoutes() {
|
|
154
|
+
this.routes.map(route => {
|
|
155
|
+
this.app.use(route.path, route.router)
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Default 404 handler for unmatched routes.
|
|
160
|
+
* Returns a JSON response with a "Not Found" message.
|
|
161
|
+
*/
|
|
162
|
+
notFoundDefault() {
|
|
163
|
+
this.app.use((req, res) => {
|
|
164
|
+
return res.status(404).json({ message: "Not Found" })
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Starts the HTTP server and begins listening for incoming connections.
|
|
169
|
+
*/
|
|
170
|
+
run() {
|
|
171
|
+
this.app.listen(this.port, () => {
|
|
172
|
+
console.log(
|
|
173
|
+
chalk.bold.blue('Blue Bird Server Online\n') +
|
|
174
|
+
chalk.bold.cyan('Host: ') + chalk.green(`${this.host}:${this.port}`) + '\n' +
|
|
175
|
+
chalk.gray('────────────────────────────────')
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export default App
|
|
182
|
+
|
package/core/auth.js
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
import jwt from "jsonwebtoken";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Auth class to handle JWT generation, verification and protection.
|
|
5
|
-
*/
|
|
6
|
-
class Auth {
|
|
7
|
-
/**
|
|
8
|
-
* Generates a JWT token.
|
|
9
|
-
* @param {Object} payload - The data to store in the token.
|
|
10
|
-
* @param {string} [secret=process.env.JWT_SECRET] - The secret key.
|
|
11
|
-
* @param {string|number} [expiresIn='24h'] - Expiration time.
|
|
12
|
-
* @returns {string} The generated token.
|
|
13
|
-
* @example
|
|
14
|
-
* const token = Auth.generateToken({ id: 1 });
|
|
15
|
-
* console.log(token);
|
|
16
|
-
*
|
|
17
|
-
*/
|
|
18
|
-
static generateToken(payload, secret = process.env.JWT_SECRET || 'blue-bird-secret', expiresIn = '24h') {
|
|
19
|
-
return jwt.sign(payload, secret, { expiresIn });
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Verifies a JWT token.
|
|
24
|
-
* @param {string} token - The token to verify.
|
|
25
|
-
* @param {string} [secret=process.env.JWT_SECRET] - The secret key.
|
|
26
|
-
* @returns {Object|null} The decoded payload or null if invalid.
|
|
27
|
-
* @example
|
|
28
|
-
* const token = Auth.generateToken({ id: 1 });
|
|
29
|
-
* const decoded = Auth.verifyToken(token);
|
|
30
|
-
* console.log(decoded);
|
|
31
|
-
*/
|
|
32
|
-
static verifyToken(token, secret = process.env.JWT_SECRET || 'blue-bird-secret') {
|
|
33
|
-
try {
|
|
34
|
-
return jwt.verify(token, secret);
|
|
35
|
-
} catch (error) {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Middleware to protect routes. Checks for token in Cookies or Authorization header.
|
|
42
|
-
* @param {Object} options - Options for protection.
|
|
43
|
-
* @param {string} [options.redirect] - URL to redirect if not authenticated (for web routes).
|
|
44
|
-
* @returns {Function} Express middleware.
|
|
45
|
-
* @example
|
|
46
|
-
* app.use(Auth.protect({ redirect: "/login" }));
|
|
47
|
-
*/
|
|
48
|
-
static protect(options = { redirect: null }) {
|
|
49
|
-
return (req, res, next) => {
|
|
50
|
-
const token = req.cookies?.token || req.headers.authorization?.split(" ")[1];
|
|
51
|
-
|
|
52
|
-
if (!token) {
|
|
53
|
-
if (options.redirect) return res.redirect(options.redirect);
|
|
54
|
-
return res.status(401).json({ message: "Unauthorized: No token provided" });
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const decoded = this.verifyToken(token);
|
|
58
|
-
if (!decoded) {
|
|
59
|
-
if (options.redirect) return res.redirect(options.redirect);
|
|
60
|
-
return res.status(401).json({ message: "Unauthorized: Invalid token" });
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
req.user = decoded;
|
|
64
|
-
next();
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export default Auth;
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Auth class to handle JWT generation, verification and protection.
|
|
5
|
+
*/
|
|
6
|
+
class Auth {
|
|
7
|
+
/**
|
|
8
|
+
* Generates a JWT token.
|
|
9
|
+
* @param {Object} payload - The data to store in the token.
|
|
10
|
+
* @param {string} [secret=process.env.JWT_SECRET] - The secret key.
|
|
11
|
+
* @param {string|number} [expiresIn='24h'] - Expiration time.
|
|
12
|
+
* @returns {string} The generated token.
|
|
13
|
+
* @example
|
|
14
|
+
* const token = Auth.generateToken({ id: 1 });
|
|
15
|
+
* console.log(token);
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
static generateToken(payload, secret = process.env.JWT_SECRET || 'blue-bird-secret', expiresIn = '24h') {
|
|
19
|
+
return jwt.sign(payload, secret, { expiresIn });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Verifies a JWT token.
|
|
24
|
+
* @param {string} token - The token to verify.
|
|
25
|
+
* @param {string} [secret=process.env.JWT_SECRET] - The secret key.
|
|
26
|
+
* @returns {Object|null} The decoded payload or null if invalid.
|
|
27
|
+
* @example
|
|
28
|
+
* const token = Auth.generateToken({ id: 1 });
|
|
29
|
+
* const decoded = Auth.verifyToken(token);
|
|
30
|
+
* console.log(decoded);
|
|
31
|
+
*/
|
|
32
|
+
static verifyToken(token, secret = process.env.JWT_SECRET || 'blue-bird-secret') {
|
|
33
|
+
try {
|
|
34
|
+
return jwt.verify(token, secret);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Middleware to protect routes. Checks for token in Cookies or Authorization header.
|
|
42
|
+
* @param {Object} options - Options for protection.
|
|
43
|
+
* @param {string} [options.redirect] - URL to redirect if not authenticated (for web routes).
|
|
44
|
+
* @returns {Function} Express middleware.
|
|
45
|
+
* @example
|
|
46
|
+
* app.use(Auth.protect({ redirect: "/login" }));
|
|
47
|
+
*/
|
|
48
|
+
static protect(options = { redirect: null }) {
|
|
49
|
+
return (req, res, next) => {
|
|
50
|
+
const token = req.cookies?.token || req.headers.authorization?.split(" ")[1];
|
|
51
|
+
|
|
52
|
+
if (!token) {
|
|
53
|
+
if (options.redirect) return res.redirect(options.redirect);
|
|
54
|
+
return res.status(401).json({ message: "Unauthorized: No token provided" });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const decoded = this.verifyToken(token);
|
|
58
|
+
if (!decoded) {
|
|
59
|
+
if (options.redirect) return res.redirect(options.redirect);
|
|
60
|
+
return res.status(401).json({ message: "Unauthorized: Invalid token" });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
req.user = decoded;
|
|
64
|
+
next();
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default Auth;
|
package/core/cli/component.js
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import Config from "../config.js";
|
|
4
|
-
|
|
5
|
-
const __dirname = Config.dirname();
|
|
6
|
-
|
|
7
|
-
class ComponentCLI {
|
|
8
|
-
/**
|
|
9
|
-
* Create component react
|
|
10
|
-
* @return {void}
|
|
11
|
-
* /
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
create() {
|
|
15
|
-
const folder = path.join(process.cwd(), "frontend/resources/components");
|
|
16
|
-
if (!fs.existsSync(folder)) {
|
|
17
|
-
fs.mkdirSync(folder, { recursive: true });
|
|
18
|
-
}
|
|
19
|
-
let nameComponent =`Component-${Math.random().toString(36).substring(7)}`;
|
|
20
|
-
const nameParam = process.argv[2];
|
|
21
|
-
if (nameParam.length > 0 && typeof nameParam === "string") {
|
|
22
|
-
nameComponent = nameParam;
|
|
23
|
-
nameComponent = nameComponent.charAt(0).toUpperCase() + nameComponent.slice(1);
|
|
24
|
-
}
|
|
25
|
-
const filePath = path.join(folder, `${nameComponent}.jsx`);
|
|
26
|
-
const content = `import React from 'react';
|
|
27
|
-
|
|
28
|
-
export default function ${nameComponent}() {
|
|
29
|
-
return (
|
|
30
|
-
<div>
|
|
31
|
-
<h1>${nameComponent} Component</h1>
|
|
32
|
-
</div>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
`;
|
|
36
|
-
fs.writeFileSync(filePath, content);
|
|
37
|
-
console.log(`Component ${nameComponent} created at ${filePath}`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const componentCLI = new ComponentCLI();
|
|
42
|
-
componentCLI.create();
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import Config from "../config.js";
|
|
4
|
+
|
|
5
|
+
const __dirname = Config.dirname();
|
|
6
|
+
|
|
7
|
+
class ComponentCLI {
|
|
8
|
+
/**
|
|
9
|
+
* Create component react
|
|
10
|
+
* @return {void}
|
|
11
|
+
* /
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
create() {
|
|
15
|
+
const folder = path.join(process.cwd(), "frontend/resources/components");
|
|
16
|
+
if (!fs.existsSync(folder)) {
|
|
17
|
+
fs.mkdirSync(folder, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
let nameComponent =`Component-${Math.random().toString(36).substring(7)}`;
|
|
20
|
+
const nameParam = process.argv[2];
|
|
21
|
+
if (nameParam.length > 0 && typeof nameParam === "string") {
|
|
22
|
+
nameComponent = nameParam;
|
|
23
|
+
nameComponent = nameComponent.charAt(0).toUpperCase() + nameComponent.slice(1);
|
|
24
|
+
}
|
|
25
|
+
const filePath = path.join(folder, `${nameComponent}.jsx`);
|
|
26
|
+
const content = `import React from 'react';
|
|
27
|
+
|
|
28
|
+
export default function ${nameComponent}() {
|
|
29
|
+
return (
|
|
30
|
+
<div>
|
|
31
|
+
<h1>${nameComponent} Component</h1>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
fs.writeFileSync(filePath, content);
|
|
37
|
+
console.log(`Component ${nameComponent} created at ${filePath}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const componentCLI = new ComponentCLI();
|
|
42
|
+
componentCLI.create();
|