powr-sdk-api 4.3.12 → 4.3.13
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/dist/admin/activities.js +81 -0
- package/dist/admin/auth.js +234 -0
- package/dist/admin/blogs.js +94 -0
- package/dist/admin/comments.js +83 -0
- package/dist/admin/files.js +56 -0
- package/dist/admin/forms.js +242 -0
- package/dist/admin/index.js +53 -0
- package/dist/admin/invoice.js +163 -0
- package/dist/admin/likes.js +126 -0
- package/dist/admin/notifications.js +93 -0
- package/dist/admin/plexx.js +53 -0
- package/dist/admin/ratings.js +189 -0
- package/dist/admin/routes.js +132 -0
- package/dist/admin/slides.js +101 -0
- package/dist/admin/users.js +175 -0
- package/dist/admin/waitlists.js +94 -0
- package/dist/index.js +3 -1
- package/dist/logger/gcs.js +78 -0
- package/dist/logger/s3.js +78 -0
- package/dist/middleware/auth.js +76 -0
- package/dist/middleware/logger.js +45 -0
- package/dist/middleware/response.js +53 -0
- package/dist/routes/admin/index.js +520 -0
- package/dist/routes/blogs.js +94 -0
- package/dist/routes/index.js +25 -1
- package/dist/routes/invoice.js +167 -0
- package/dist/routes/plexx.js +269 -0
- package/dist/routes/routes.js +143 -0
- package/dist/services/dbService.js +42 -0
- package/dist/services/functions.js +229 -0
- package/dist/services/logger.js +35 -0
- package/dist/services/plexx.js +229 -0
- package/dist/utils/auth.js +19 -0
- package/dist/utils/logger.js +57 -0
- package/dist/utils/s3-transport.js +61 -0
- package/dist/utils/s3.js +78 -0
- package/package.json +69 -69
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const express = require("express");
|
|
4
|
+
const router = express.Router();
|
|
5
|
+
const {
|
|
6
|
+
getDb
|
|
7
|
+
} = require("../services/mongo");
|
|
8
|
+
|
|
9
|
+
// Get waitlist entries
|
|
10
|
+
router.get('/', async (req, res) => {
|
|
11
|
+
const {
|
|
12
|
+
projectId
|
|
13
|
+
} = req.query;
|
|
14
|
+
try {
|
|
15
|
+
const query = {
|
|
16
|
+
projectId
|
|
17
|
+
};
|
|
18
|
+
console.log("Filter.....:", query);
|
|
19
|
+
const waitlistData = await getDb().collection("waitlists").find(query).toArray();
|
|
20
|
+
if (!waitlistData || waitlistData.length === 0) {
|
|
21
|
+
console.log("Data not found.");
|
|
22
|
+
return res.status(200).json({
|
|
23
|
+
success: true,
|
|
24
|
+
entries: []
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const sortedData = waitlistData.sort((a, b) => new Date(b === null || b === void 0 ? void 0 : b.createdAt) - new Date(a === null || a === void 0 ? void 0 : a.createdAt));
|
|
28
|
+
console.log("Waitlist entries retrieved and sorted:", sortedData);
|
|
29
|
+
return res.status(200).json({
|
|
30
|
+
success: true,
|
|
31
|
+
entries: sortedData
|
|
32
|
+
});
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error("Error retrieving waitlist entries:", error);
|
|
35
|
+
return res.status(500).json({
|
|
36
|
+
success: false,
|
|
37
|
+
message: "Failed to retrieve waitlist entries."
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Original POST endpoint for adding to waitlist
|
|
43
|
+
router.post("/", async (req, res) => {
|
|
44
|
+
const {
|
|
45
|
+
projectId,
|
|
46
|
+
email
|
|
47
|
+
} = req.body;
|
|
48
|
+
try {
|
|
49
|
+
const existingEntry = await getDb().collection("waitlists").findOne({
|
|
50
|
+
projectId,
|
|
51
|
+
email
|
|
52
|
+
});
|
|
53
|
+
if (existingEntry) {
|
|
54
|
+
return res.status(400).json({
|
|
55
|
+
success: false,
|
|
56
|
+
message: "You are already in the waitlist "
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error("Error checking waitlist:", error);
|
|
61
|
+
return res.status(500).json({
|
|
62
|
+
success: false,
|
|
63
|
+
message: "Failed to check waitlist due to a server error."
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const waitListData = {
|
|
67
|
+
projectId,
|
|
68
|
+
email,
|
|
69
|
+
createdAt: new Date()
|
|
70
|
+
};
|
|
71
|
+
try {
|
|
72
|
+
const result = await getDb().collection("waitlists").insertOne(waitListData);
|
|
73
|
+
if (result && result.insertedId) {
|
|
74
|
+
return res.status(200).json({
|
|
75
|
+
success: true,
|
|
76
|
+
message: "you are added in the waitist",
|
|
77
|
+
userId: result.insertedId
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
console.error("Insert operation failed. Result:", result);
|
|
81
|
+
return res.status(500).json({
|
|
82
|
+
success: false,
|
|
83
|
+
message: "user could not be added."
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error("Error adding user:", error);
|
|
88
|
+
return res.status(500).json({
|
|
89
|
+
success: false,
|
|
90
|
+
message: "Failed to add user due to a server error."
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
module.exports = router;
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,8 @@ const {
|
|
|
14
14
|
createSwaggerSpec
|
|
15
15
|
} = require("./swagger");
|
|
16
16
|
const {
|
|
17
|
-
createPowrRoutes
|
|
17
|
+
createPowrRoutes,
|
|
18
|
+
createCommonRoutes
|
|
18
19
|
} = require("./routes");
|
|
19
20
|
const {
|
|
20
21
|
initializeFunctions,
|
|
@@ -33,6 +34,7 @@ module.exports = {
|
|
|
33
34
|
createSwaggerSpec,
|
|
34
35
|
notFoundHandler,
|
|
35
36
|
createPowrRoutes,
|
|
37
|
+
createCommonRoutes,
|
|
36
38
|
initializeFunctions,
|
|
37
39
|
initializeTools,
|
|
38
40
|
verifyToken,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const winston = require('winston');
|
|
4
|
+
const {
|
|
5
|
+
Storage
|
|
6
|
+
} = require('@google-cloud/storage');
|
|
7
|
+
|
|
8
|
+
// Create GCS client using environment variables for credentials
|
|
9
|
+
const storage = new Storage({
|
|
10
|
+
projectId: process.env.GCS_PROJECT_ID,
|
|
11
|
+
credentials: {
|
|
12
|
+
client_email: process.env.GCS_CLIENT_EMAIL,
|
|
13
|
+
private_key: process.env.GCS_PRIVATE_KEY ? process.env.GCS_PRIVATE_KEY.replace(/\\n/g, '\n') : undefined
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Custom Winston transport for logging to Google Cloud Storage
|
|
19
|
+
*/
|
|
20
|
+
class GCSTransport extends winston.Transport {
|
|
21
|
+
constructor(opts) {
|
|
22
|
+
super(opts);
|
|
23
|
+
this.bucket = opts.bucket;
|
|
24
|
+
this.prefix = opts.prefix || '';
|
|
25
|
+
this.buffer = [];
|
|
26
|
+
this.bufferSize = opts.bufferSize || 100;
|
|
27
|
+
this.flushInterval = opts.flushInterval || 5000;
|
|
28
|
+
this.setupFlushInterval();
|
|
29
|
+
}
|
|
30
|
+
setupFlushInterval() {
|
|
31
|
+
setInterval(() => {
|
|
32
|
+
this.flush();
|
|
33
|
+
}, this.flushInterval);
|
|
34
|
+
}
|
|
35
|
+
async flush() {
|
|
36
|
+
if (this.buffer.length === 0) return;
|
|
37
|
+
const logs = this.buffer.splice(0, this.buffer.length);
|
|
38
|
+
const date = new Date().toISOString().split('T')[0];
|
|
39
|
+
const filename = `${this.prefix}/${date}/${Date.now()}.json`;
|
|
40
|
+
try {
|
|
41
|
+
const bucket = storage.bucket(this.bucket);
|
|
42
|
+
const file = bucket.file(filename);
|
|
43
|
+
await file.save(JSON.stringify(logs), {
|
|
44
|
+
contentType: 'application/json',
|
|
45
|
+
metadata: {
|
|
46
|
+
contentType: 'application/json'
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('Failed to write logs to Google Cloud Storage:', {
|
|
51
|
+
error: error.message,
|
|
52
|
+
code: error.code,
|
|
53
|
+
bucket: this.bucket,
|
|
54
|
+
filename: filename,
|
|
55
|
+
projectId: process.env.GCS_PROJECT_ID,
|
|
56
|
+
stack: error.stack
|
|
57
|
+
});
|
|
58
|
+
// Put the logs back in the buffer
|
|
59
|
+
this.buffer.unshift(...logs);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
log(info, callback) {
|
|
63
|
+
setImmediate(() => {
|
|
64
|
+
this.emit('logged', info);
|
|
65
|
+
});
|
|
66
|
+
this.buffer.push({
|
|
67
|
+
timestamp: new Date().toISOString(),
|
|
68
|
+
...info
|
|
69
|
+
});
|
|
70
|
+
if (this.buffer.length >= this.bufferSize) {
|
|
71
|
+
this.flush();
|
|
72
|
+
}
|
|
73
|
+
callback();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
module.exports = {
|
|
77
|
+
GCSTransport
|
|
78
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const winston = require('winston');
|
|
4
|
+
const {
|
|
5
|
+
S3Client,
|
|
6
|
+
PutObjectCommand
|
|
7
|
+
} = require('@aws-sdk/client-s3');
|
|
8
|
+
|
|
9
|
+
// Create S3 client
|
|
10
|
+
const s3Client = new S3Client({
|
|
11
|
+
region: process.env.AWS_REGION,
|
|
12
|
+
credentials: {
|
|
13
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
14
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Custom Winston transport for logging to S3
|
|
20
|
+
*/
|
|
21
|
+
class S3Transport extends winston.Transport {
|
|
22
|
+
constructor(opts) {
|
|
23
|
+
super(opts);
|
|
24
|
+
this.bucket = opts.bucket;
|
|
25
|
+
this.prefix = opts.prefix || '';
|
|
26
|
+
this.buffer = [];
|
|
27
|
+
this.bufferSize = opts.bufferSize || 100;
|
|
28
|
+
this.flushInterval = opts.flushInterval || 5000;
|
|
29
|
+
this.setupFlushInterval();
|
|
30
|
+
}
|
|
31
|
+
setupFlushInterval() {
|
|
32
|
+
setInterval(() => {
|
|
33
|
+
this.flush();
|
|
34
|
+
}, this.flushInterval);
|
|
35
|
+
}
|
|
36
|
+
async flush() {
|
|
37
|
+
if (this.buffer.length === 0) return;
|
|
38
|
+
const logs = this.buffer.splice(0, this.buffer.length);
|
|
39
|
+
const date = new Date().toISOString().split('T')[0];
|
|
40
|
+
const key = `${this.prefix}/${date}/${Date.now()}.json`;
|
|
41
|
+
try {
|
|
42
|
+
const command = new PutObjectCommand({
|
|
43
|
+
Bucket: this.bucket,
|
|
44
|
+
Key: key,
|
|
45
|
+
Body: JSON.stringify(logs),
|
|
46
|
+
ContentType: 'application/json'
|
|
47
|
+
});
|
|
48
|
+
await s3Client.send(command);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('Failed to write logs to S3:', {
|
|
51
|
+
error: error.message,
|
|
52
|
+
code: error.code,
|
|
53
|
+
bucket: this.bucket,
|
|
54
|
+
key: key,
|
|
55
|
+
region: process.env.AWS_REGION,
|
|
56
|
+
stack: error.stack
|
|
57
|
+
});
|
|
58
|
+
// Put the logs back in the buffer
|
|
59
|
+
this.buffer.unshift(...logs);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
log(info, callback) {
|
|
63
|
+
setImmediate(() => {
|
|
64
|
+
this.emit('logged', info);
|
|
65
|
+
});
|
|
66
|
+
this.buffer.push({
|
|
67
|
+
timestamp: new Date().toISOString(),
|
|
68
|
+
...info
|
|
69
|
+
});
|
|
70
|
+
if (this.buffer.length >= this.bufferSize) {
|
|
71
|
+
this.flush();
|
|
72
|
+
}
|
|
73
|
+
callback();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
module.exports = {
|
|
77
|
+
S3Transport
|
|
78
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const jwt = require("jsonwebtoken");
|
|
4
|
+
const generateToken = user => {
|
|
5
|
+
return jwt.sign({
|
|
6
|
+
userId: user.userId
|
|
7
|
+
}, process.env.JWT_SECRET, {
|
|
8
|
+
expiresIn: process.env.JWT_EXPIRES_IN || '24h'
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const validateToken = async (req, res, next) => {
|
|
12
|
+
try {
|
|
13
|
+
let token;
|
|
14
|
+
|
|
15
|
+
// Check if token exists in headers
|
|
16
|
+
if (req.headers.authorization && req.headers.authorization.startsWith("Bearer")) {
|
|
17
|
+
token = req.headers.authorization.split(" ")[1];
|
|
18
|
+
}
|
|
19
|
+
if (!token) {
|
|
20
|
+
return res.error("Not authorized to access this route", 401);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
// Verify token
|
|
24
|
+
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
|
25
|
+
|
|
26
|
+
// // Get user from token
|
|
27
|
+
// const user = await User.findByPk(decoded.userId);
|
|
28
|
+
// if (!user) {
|
|
29
|
+
// return res.error('User not found', 401);
|
|
30
|
+
// }
|
|
31
|
+
|
|
32
|
+
// // Add user and userId to request object
|
|
33
|
+
// req.user = user;
|
|
34
|
+
req.userId = decoded.userId;
|
|
35
|
+
next();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return res.error("Not authorized to access this route", 401, error);
|
|
38
|
+
}
|
|
39
|
+
} catch (error) {
|
|
40
|
+
return res.error("Error authenticating user", 500, error);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const validateAuth = (options = {}) => {
|
|
44
|
+
const {
|
|
45
|
+
publicPaths = ["/auth", "/", "/status", "/swagger"],
|
|
46
|
+
publicMethods = ["OPTIONS"]
|
|
47
|
+
} = options;
|
|
48
|
+
return async (req, res, next) => {
|
|
49
|
+
// Skip auth validation for public paths
|
|
50
|
+
if (publicPaths.some(path => req.path.startsWith(path))) {
|
|
51
|
+
return next();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Skip auth validation for public methods
|
|
55
|
+
if (publicMethods.includes(req.method)) {
|
|
56
|
+
return next();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Use the original validateToken middleware for protected routes
|
|
60
|
+
return validateToken(req, res, next);
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// exports.authorize = (...roles) => {
|
|
65
|
+
// return (req, res, next) => {
|
|
66
|
+
// if (!roles.includes(req.user.role)) {
|
|
67
|
+
// return res.error(`User role ${req.user.role} is not authorized to access this route`, 403);
|
|
68
|
+
// }
|
|
69
|
+
// next();
|
|
70
|
+
// };
|
|
71
|
+
// };
|
|
72
|
+
|
|
73
|
+
module.exports = {
|
|
74
|
+
validateAuth,
|
|
75
|
+
generateToken
|
|
76
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Logging middleware for Express applications
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const logger = (req, res, next) => {
|
|
8
|
+
const startTime = Date.now();
|
|
9
|
+
|
|
10
|
+
// Log request with redacted sensitive information
|
|
11
|
+
try {
|
|
12
|
+
const logBody = {
|
|
13
|
+
...req.body
|
|
14
|
+
};
|
|
15
|
+
if (logBody.password) logBody.password = "[REDACTED]";
|
|
16
|
+
if (logBody.token) logBody.token = "[REDACTED]";
|
|
17
|
+
console.log('Request:', {
|
|
18
|
+
timestamp: new Date().toISOString(),
|
|
19
|
+
method: req.method,
|
|
20
|
+
url: req.originalUrl,
|
|
21
|
+
ip: req.ip,
|
|
22
|
+
userAgent: req.get('user-agent'),
|
|
23
|
+
body: logBody,
|
|
24
|
+
query: req.query
|
|
25
|
+
});
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error("Error logging request:", error);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Log response with timing information
|
|
31
|
+
res.on('finish', () => {
|
|
32
|
+
const responseTime = Date.now() - startTime;
|
|
33
|
+
console.log('Response:', {
|
|
34
|
+
timestamp: new Date().toISOString(),
|
|
35
|
+
method: req.method,
|
|
36
|
+
url: req.originalUrl,
|
|
37
|
+
statusCode: res.statusCode,
|
|
38
|
+
responseTime: `${responseTime}ms`,
|
|
39
|
+
userAgent: req.get('user-agent'),
|
|
40
|
+
ip: req.ip
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
next();
|
|
44
|
+
};
|
|
45
|
+
module.exports = logger;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const logger = require('../services/logger');
|
|
4
|
+
const responseFormatter = (req, res, next) => {
|
|
5
|
+
// Add success method to response object
|
|
6
|
+
res.success = function (message = 'Success', statusCode = 200, data = null) {
|
|
7
|
+
const response = {
|
|
8
|
+
success: true,
|
|
9
|
+
message
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// Only include data if it's not null
|
|
13
|
+
if (data !== null) {
|
|
14
|
+
response.data = data;
|
|
15
|
+
}
|
|
16
|
+
return this.status(statusCode).json(response);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Add error method to response object
|
|
20
|
+
res.error = function (message = 'Error', statusCode = 500, error = null) {
|
|
21
|
+
const response = {
|
|
22
|
+
success: false,
|
|
23
|
+
message
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Only include details if they're not null
|
|
27
|
+
if (error !== null) {
|
|
28
|
+
response.error = error;
|
|
29
|
+
}
|
|
30
|
+
return this.status(statusCode).json(response);
|
|
31
|
+
};
|
|
32
|
+
next();
|
|
33
|
+
};
|
|
34
|
+
const responseLogger = (req, res, next) => {
|
|
35
|
+
const startTime = Date.now();
|
|
36
|
+
res.on('finish', () => {
|
|
37
|
+
const responseTime = Date.now() - startTime;
|
|
38
|
+
logger.info('API Response', {
|
|
39
|
+
method: req.method,
|
|
40
|
+
url: req.originalUrl,
|
|
41
|
+
statusCode: res.statusCode,
|
|
42
|
+
responseTime: `${responseTime}ms`,
|
|
43
|
+
userAgent: req.get('user-agent'),
|
|
44
|
+
ip: req.ip,
|
|
45
|
+
response: res.locals.responseBody || '[not captured]'
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
next();
|
|
49
|
+
};
|
|
50
|
+
module.exports = {
|
|
51
|
+
responseFormatter,
|
|
52
|
+
responseLogger
|
|
53
|
+
};
|