@diagramers/cli 1.0.24 → 1.0.25
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/services/template-updater.d.ts +0 -1
- package/dist/services/template-updater.d.ts.map +1 -1
- package/dist/services/template-updater.js +2 -41
- package/dist/services/template-updater.js.map +1 -1
- package/package.json +1 -1
- package/templates/api/certs/auth-app-cert.json +0 -13
- package/templates/api/main.ts +0 -10
- package/templates/api/package.json +0 -70
- package/templates/api/src/assets/css/email-template.css +0 -8
- package/templates/api/src/assets/images/logo_large.png +0 -0
- package/templates/api/src/assets/keys/certificate.pem +0 -22
- package/templates/api/src/assets/keys/private-key.pem +0 -28
- package/templates/api/src/config/config-interface.ts +0 -191
- package/templates/api/src/config/development.ts +0 -145
- package/templates/api/src/config/index.ts +0 -59
- package/templates/api/src/config/production.ts +0 -145
- package/templates/api/src/config/staging.ts +0 -144
- package/templates/api/src/config/uat.ts +0 -144
- package/templates/api/src/controllers/account-controller.ts +0 -162
- package/templates/api/src/entities/audit.ts +0 -12
- package/templates/api/src/entities/base-entity.ts +0 -10
- package/templates/api/src/entities/user.ts +0 -71
- package/templates/api/src/helpers/FrameworkHelper.ts +0 -157
- package/templates/api/src/helpers/auth.ts +0 -971
- package/templates/api/src/helpers/cronHelper.ts +0 -170
- package/templates/api/src/helpers/dbcontext.ts +0 -83
- package/templates/api/src/helpers/encryptionHelper.ts +0 -76
- package/templates/api/src/helpers/enums.ts +0 -258
- package/templates/api/src/helpers/handle-response.ts +0 -49
- package/templates/api/src/helpers/httpHelper.ts +0 -75
- package/templates/api/src/helpers/mailer.ts +0 -152
- package/templates/api/src/helpers/result.ts +0 -47
- package/templates/api/src/helpers/string-helper.ts +0 -27
- package/templates/api/src/routes/account-routes.ts +0 -37
- package/templates/api/src/routes/auth-routes.ts +0 -286
- package/templates/api/src/routes/index.ts +0 -92
- package/templates/api/src/schemas/audit.ts +0 -36
- package/templates/api/src/schemas/otp.ts +0 -52
- package/templates/api/src/schemas/session.ts +0 -57
- package/templates/api/src/schemas/user.ts +0 -125
- package/templates/api/src/server/index.ts +0 -86
- package/templates/api/src/server/socket-server-provider.ts +0 -209
- package/templates/api/src/services/account-service.ts +0 -243
- package/templates/api/src/services/audit-service.ts +0 -56
- package/templates/api/tsconfig.json +0 -16
- package/templates/api/webpack.config.js +0 -66
@@ -1,152 +0,0 @@
|
|
1
|
-
import NodeMailer = require('nodemailer');
|
2
|
-
// import hbs = require('nodemailer-express-handlebars');
|
3
|
-
import * as path from 'path'
|
4
|
-
|
5
|
-
class Mailer {
|
6
|
-
CreateTransport() {
|
7
|
-
// Load DKIM private key from a file or environment variable
|
8
|
-
|
9
|
-
const transporter = NodeMailer.createTransport({
|
10
|
-
host: 'SMTP.Bmail.linkdatacenter.net',
|
11
|
-
port: 465,
|
12
|
-
secure: true, // Set to true for SSL/TLS
|
13
|
-
auth: {
|
14
|
-
user: 'no-reply@sendifier.com',
|
15
|
-
pass: 'Sendifieris12!',
|
16
|
-
}
|
17
|
-
});
|
18
|
-
return transporter;
|
19
|
-
}
|
20
|
-
|
21
|
-
GetActivationEmailTemplate(contactName, businessName, buttonLink, buttonText) {
|
22
|
-
return `
|
23
|
-
<!DOCTYPE html>
|
24
|
-
<html lang="en">
|
25
|
-
<head>
|
26
|
-
<meta charset="UTF-8">
|
27
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
28
|
-
</head>
|
29
|
-
<body>
|
30
|
-
<table style="margin:auto;" role="presentation" cellspacing="0" cellpadding="0" border="0" align="center">
|
31
|
-
<tbody>
|
32
|
-
<tr>
|
33
|
-
<td style="background-color:#ffffff;padding:20px;text-align:center;">
|
34
|
-
<p><img class="image_resized" style="margin-bottom:20px;width:56.11%;" src="https://firebasestorage.googleapis.com/v0/b/sendifier-web-app.appspot.com/o/assets%2Flogos%2Flogo-blue-light.svg?alt=media&token=13409730-e669-4268-bbc7-fede7d023fee" alt="Company Logo" width="150"></p>
|
35
|
-
<h2 style="color:#333333;">Invitation from ${businessName}!</h2>
|
36
|
-
<p style="color:#555555;font-size:16px;">Hi ${contactName}, you have been invited to join ${businessName} account on 'Sendifier!', if you're expecting that invitation please click on the verification link below, otherwise please ignore this email.</p>
|
37
|
-
<figure class="table">
|
38
|
-
<table style="margin:auto;" role="presentation" cellspacing="0" cellpadding="0" border="0" align="center">
|
39
|
-
<tbody>
|
40
|
-
<tr>
|
41
|
-
<td style="background-color:#007bff;border-radius:5px;text-align:center;"><a style="background-color:#007bff;border-radius:5px;color:#ffffff;display:inline-block;padding:10px 20px;text-decoration:none;" href="${buttonLink}" target="_blank">${buttonText}</a></td>
|
42
|
-
</tr>
|
43
|
-
</tbody>
|
44
|
-
</table>
|
45
|
-
</figure>
|
46
|
-
</td>
|
47
|
-
</tr>
|
48
|
-
</tbody>
|
49
|
-
</table>
|
50
|
-
</body>
|
51
|
-
</html>
|
52
|
-
`
|
53
|
-
};
|
54
|
-
|
55
|
-
|
56
|
-
GetResetPasswordTemplate(contactName, buttonLink, buttonText) {
|
57
|
-
return `
|
58
|
-
<!DOCTYPE html>
|
59
|
-
<html lang="en">
|
60
|
-
<head>
|
61
|
-
<meta charset="UTF-8">
|
62
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
63
|
-
</head>
|
64
|
-
<body>
|
65
|
-
<table style="margin:auto;" role="presentation" cellspacing="0" cellpadding="0" border="0" align="center">
|
66
|
-
<tbody>
|
67
|
-
<tr>
|
68
|
-
<td style="background-color:#ffffff;padding:20px;text-align:center;">
|
69
|
-
<p><img class="image_resized" style="margin-bottom:20px;width:56.11%;" src="https://firebasestorage.googleapis.com/v0/b/sendifier-web-app.appspot.com/o/assets%2Flogos%2Flogo-blue-light.svg?alt=media&token=13409730-e669-4268-bbc7-fede7d023fee" alt="Company Logo" width="150"></p>
|
70
|
-
<h2 style="color:#333333;">Reset password request</h2>
|
71
|
-
<p style="color:#555555;font-size:16px;">Hi ${contactName}, we received a request to reset the password for this email, if you want to reset your password please follow the following link.</p>
|
72
|
-
<figure class="table">
|
73
|
-
<table style="margin:auto;" role="presentation" cellspacing="0" cellpadding="0" border="0" align="center">
|
74
|
-
<tbody>
|
75
|
-
<tr>
|
76
|
-
<td style="background-color:#007bff;border-radius:5px;text-align:center;"><a style="background-color:#007bff;border-radius:5px;color:#ffffff;display:inline-block;padding:10px 20px;text-decoration:none;" href="${buttonLink}" target="_blank">${buttonText}</a></td>
|
77
|
-
</tr>
|
78
|
-
</tbody>
|
79
|
-
</table>
|
80
|
-
</figure>
|
81
|
-
</td>
|
82
|
-
</tr>
|
83
|
-
</tbody>
|
84
|
-
</table>
|
85
|
-
</body>
|
86
|
-
</html>
|
87
|
-
`
|
88
|
-
};
|
89
|
-
|
90
|
-
GetEmailConfirmationTemplate(contactName, buttonLink, buttonText) {
|
91
|
-
return `
|
92
|
-
<!DOCTYPE html>
|
93
|
-
<html lang="en">
|
94
|
-
<head>
|
95
|
-
<meta charset="UTF-8">
|
96
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
97
|
-
</head>
|
98
|
-
<body>
|
99
|
-
<table style="margin:auto;" role="presentation" cellspacing="0" cellpadding="0" border="0" align="center">
|
100
|
-
<tbody>
|
101
|
-
<tr>
|
102
|
-
<td style="background-color:#ffffff;padding:20px;text-align:center;">
|
103
|
-
<p><img class="image_resized" style="margin-bottom:20px;width:56.11%;" src="https://firebasestorage.googleapis.com/v0/b/sendifier-web-app.appspot.com/o/assets%2Flogos%2Flogo-blue-light.svg?alt=media&token=13409730-e669-4268-bbc7-fede7d023fee" alt="Company Logo" width="150"></p>
|
104
|
-
<h2 style="color:#333333;">Email Confirmation</h2>
|
105
|
-
<p style="color:#555555;font-size:16px;">Hi ${contactName}, in order to complete your registeration on Sendifier! platform, you need to confirm your ownership of this email, please confirm.</p>
|
106
|
-
<figure class="table">
|
107
|
-
<table style="margin:auto;" role="presentation" cellspacing="0" cellpadding="0" border="0" align="center">
|
108
|
-
<tbody>
|
109
|
-
<tr>
|
110
|
-
<td style="background-color:#007bff;border-radius:5px;text-align:center;"><a style="background-color:#007bff;border-radius:5px;color:#ffffff;display:inline-block;padding:10px 20px;text-decoration:none;" href="${buttonLink}" target="_blank">${buttonText}</a></td>
|
111
|
-
</tr>
|
112
|
-
</tbody>
|
113
|
-
</table>
|
114
|
-
</figure>
|
115
|
-
</td>
|
116
|
-
</tr>
|
117
|
-
</tbody>
|
118
|
-
</table>
|
119
|
-
</body>
|
120
|
-
</html>
|
121
|
-
`
|
122
|
-
};
|
123
|
-
async SendEmail(to, view, subject, attachments = [], props = {}) {
|
124
|
-
try {
|
125
|
-
// Detailed logging to understand the parameters being passed
|
126
|
-
console.log({ to, view, subject, attachments, props });
|
127
|
-
|
128
|
-
// Validate the 'to' parameter
|
129
|
-
if (!to || typeof to !== 'string' || !to.includes('@')) {
|
130
|
-
throw new Error('Invalid email address provided');
|
131
|
-
}
|
132
|
-
|
133
|
-
var transporter = this.CreateTransport();
|
134
|
-
var response = await transporter.sendMail({
|
135
|
-
to: to,
|
136
|
-
subject: `Sendifier! ${subject}`,
|
137
|
-
from: 'no-reply@sendifier.com',
|
138
|
-
html: view,
|
139
|
-
alternatives: props,
|
140
|
-
// text: text,
|
141
|
-
// attachments: attachments,
|
142
|
-
});
|
143
|
-
|
144
|
-
return true;
|
145
|
-
} catch (ex) {
|
146
|
-
console.error('Error sending email:', ex);
|
147
|
-
return false;
|
148
|
-
}
|
149
|
-
}
|
150
|
-
|
151
|
-
}
|
152
|
-
export const MailHelper = new Mailer();
|
@@ -1,47 +0,0 @@
|
|
1
|
-
import { ResponseCode, AuditMessageType } from "./enums";
|
2
|
-
|
3
|
-
export class Result<T = any> {
|
4
|
-
constructor(data: any, status: ResponseCode, Errors: any[] = [], Messages: any[] = null, RequestIdentifier: string = null, additionalInfo: any = null, user: any = null) {
|
5
|
-
this.Data = data;
|
6
|
-
this.Status = status;
|
7
|
-
this.Errors = Errors;
|
8
|
-
this.Messages = Messages;
|
9
|
-
this.RequrestIdentifier = RequestIdentifier;
|
10
|
-
this.additionalInfo = additionalInfo;
|
11
|
-
this.user = user;
|
12
|
-
}
|
13
|
-
Data: T;
|
14
|
-
Status: ResponseCode;
|
15
|
-
Errors: any[];
|
16
|
-
RequrestIdentifier: string;
|
17
|
-
Messages: any[];
|
18
|
-
additionalInfo: any;
|
19
|
-
user: any;
|
20
|
-
StatusMessage: String;
|
21
|
-
addMessage = (type: AuditMessageType, className, methodName, message) => {
|
22
|
-
if (!this.Messages) {
|
23
|
-
this.Messages = [];
|
24
|
-
}
|
25
|
-
this.Messages.push({
|
26
|
-
requestIdentifier: this.RequrestIdentifier,
|
27
|
-
logtime: new Date(),
|
28
|
-
type: type,
|
29
|
-
className: className,
|
30
|
-
methodName: methodName,
|
31
|
-
message: message
|
32
|
-
})
|
33
|
-
};
|
34
|
-
addException = (className, methodName, ex) => {
|
35
|
-
if (!this.Errors) {
|
36
|
-
this.Errors = [];
|
37
|
-
}
|
38
|
-
this.Errors.push({
|
39
|
-
requestIdentifier: this.RequrestIdentifier,
|
40
|
-
logtime: new Date(),
|
41
|
-
type: AuditMessageType.exception,
|
42
|
-
className: className,
|
43
|
-
methodName: methodName,
|
44
|
-
message: ex
|
45
|
-
})
|
46
|
-
}
|
47
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
class StringMethods {
|
2
|
-
constructor() {
|
3
|
-
|
4
|
-
}
|
5
|
-
|
6
|
-
GetRandomString(length) {
|
7
|
-
var randomChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
8
|
-
var result = '';
|
9
|
-
for (var i = 0; i < length; i++) {
|
10
|
-
result += randomChars.charAt(Math.floor(Math.random() * randomChars.length));
|
11
|
-
}
|
12
|
-
return result;
|
13
|
-
}
|
14
|
-
|
15
|
-
ToBase64(data: string) {
|
16
|
-
let buff = new Buffer(data);
|
17
|
-
let base64data = buff.toString('base64');
|
18
|
-
return base64data;
|
19
|
-
}
|
20
|
-
|
21
|
-
FromBase64(data: string) {
|
22
|
-
let buff = new Buffer(data, 'base64');
|
23
|
-
let text = buff.toString('ascii');
|
24
|
-
return text;
|
25
|
-
}
|
26
|
-
}
|
27
|
-
export const StringHelper = new StringMethods();
|
@@ -1,37 +0,0 @@
|
|
1
|
-
import * as express from "express";
|
2
|
-
import AccountController from "../controllers/account-controller";
|
3
|
-
|
4
|
-
class AccountRoutes {
|
5
|
-
public Router: express.Router = express.Router();
|
6
|
-
private Controller: AccountController = new AccountController();
|
7
|
-
|
8
|
-
constructor() {
|
9
|
-
this.registerRoutes();
|
10
|
-
}
|
11
|
-
|
12
|
-
private registerRoutes() {
|
13
|
-
this.Router.get('/', (req, res) => {
|
14
|
-
res.send("Account API is up.");
|
15
|
-
});
|
16
|
-
|
17
|
-
// Seed user for initial admin setup
|
18
|
-
this.Router.get('/seed-user', (req, res) => this.Controller.seedUser(req, res));
|
19
|
-
|
20
|
-
// Authentication and account routes
|
21
|
-
this.Router.post('/verify-token', (req, res) => this.Controller.verifyToken(req, res));
|
22
|
-
this.Router.post('/activate-email', (req, res) => this.Controller.activateEmail(req, res));
|
23
|
-
this.Router.post('/register', (req, res) => this.Controller.register(req, res));
|
24
|
-
this.Router.post('/login', (req, res) => this.Controller.login(req, res));
|
25
|
-
this.Router.post('/complete-signup', (req, res) => this.Controller.completeSignup(req, res));
|
26
|
-
this.Router.post('/verify-email', (req, res) => this.Controller.activateEmail(req, res));
|
27
|
-
this.Router.post('/sendmail', (req, res) => this.Controller.sendSignUpEmail(req, res));
|
28
|
-
this.Router.post('/isEmailLinkedToBusiness', (req, res) => this.Controller.checkEmailIsExistForBusiness(req, res));
|
29
|
-
this.Router.post('/isPhoneLinkedToBusiness', (req, res) => this.Controller.checkPhoneIsExistForBusiness(req, res));
|
30
|
-
|
31
|
-
// Optional: add password reset routes if implemented in AccountController
|
32
|
-
// this.Router.post('/reset-password', (req, res) => this.Controller.resetUserPassword(req, res));
|
33
|
-
// this.Router.post('/request-reset-password', (req, res) => this.Controller.requestResetUserPassword(req, res));
|
34
|
-
}
|
35
|
-
}
|
36
|
-
|
37
|
-
export const accountRouter = new AccountRoutes().Router;
|
@@ -1,286 +0,0 @@
|
|
1
|
-
import * as express from "express";
|
2
|
-
import AccountController from "../controllers/account-controller";
|
3
|
-
import { AuthHelper } from "../helpers/auth";
|
4
|
-
import { Result } from "../helpers/result";
|
5
|
-
import { ResponseCode, AuditMessageType } from "../helpers/enums";
|
6
|
-
import handleResponse from "../helpers/handle-response";
|
7
|
-
|
8
|
-
class AuthRoutes {
|
9
|
-
Router: express.Router = express.Router();
|
10
|
-
Controller: AccountController = new AccountController();
|
11
|
-
|
12
|
-
constructor() {
|
13
|
-
this.registerRoutes();
|
14
|
-
}
|
15
|
-
|
16
|
-
registerRoutes() {
|
17
|
-
// Health check
|
18
|
-
this.Router.get('/', (req, res) => {
|
19
|
-
const result = new Result({
|
20
|
-
message: 'Auth service is running',
|
21
|
-
enabled_providers: ['internal', 'firebase', 'oauth', 'sms_otp', 'email_otp'],
|
22
|
-
timestamp: new Date().toISOString()
|
23
|
-
}, ResponseCode.Ok);
|
24
|
-
res.json(result);
|
25
|
-
});
|
26
|
-
|
27
|
-
// Legacy routes (for backward compatibility)
|
28
|
-
this.Router.post('/verify-token', this.Controller.verifyToken);
|
29
|
-
this.Router.post('/activate-email', this.Controller.activateEmail);
|
30
|
-
this.Router.post('/register', this.Controller.register);
|
31
|
-
this.Router.post('/login', this.Controller.login);
|
32
|
-
this.Router.post('/verify-signup-code', this.Controller.verifySignupCode);
|
33
|
-
this.Router.post('/verify-email', this.Controller.activateEmail);
|
34
|
-
this.Router.post('/complete-signup', this.Controller.completeSignup);
|
35
|
-
this.Router.post('/reset-password', this.Controller.resetUserPassword);
|
36
|
-
this.Router.post('/request-reset-password', this.Controller.requestResetUserPassword);
|
37
|
-
|
38
|
-
// New multi-provider authentication routes
|
39
|
-
this.Router.post('/register-password', this.registerWithPassword.bind(this));
|
40
|
-
this.Router.post('/login-password', this.loginWithPassword.bind(this));
|
41
|
-
this.Router.post('/firebase', this.authenticateWithFirebase.bind(this));
|
42
|
-
this.Router.post('/oauth', this.authenticateWithOAuth.bind(this));
|
43
|
-
this.Router.post('/sms/send-otp', this.sendSMSOTP.bind(this));
|
44
|
-
this.Router.post('/sms/verify-otp', this.verifySMSOTP.bind(this));
|
45
|
-
this.Router.post('/email/send-otp', this.sendEmailOTP.bind(this));
|
46
|
-
this.Router.post('/verify-session', this.verifySession.bind(this));
|
47
|
-
this.Router.post('/logout', this.logout.bind(this));
|
48
|
-
}
|
49
|
-
|
50
|
-
// Internal Authentication
|
51
|
-
async registerWithPassword(req: express.Request, res: express.Response) {
|
52
|
-
const result = res.locals.result;
|
53
|
-
try {
|
54
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'registerWithPassword', 'Started');
|
55
|
-
|
56
|
-
const { name, email, password, phone } = req.body;
|
57
|
-
|
58
|
-
// Validate required fields
|
59
|
-
if (!name || !email || !password) {
|
60
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
61
|
-
result.Errors.push('Name, email, and password are required');
|
62
|
-
return handleResponse(req, res, result);
|
63
|
-
}
|
64
|
-
|
65
|
-
const authHelper = new AuthHelper(result);
|
66
|
-
const serviceResult = await authHelper.registerWithPassword({ name, email, password, phone });
|
67
|
-
|
68
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'registerWithPassword', 'Finished');
|
69
|
-
return handleResponse(req, res, serviceResult);
|
70
|
-
} catch (ex) {
|
71
|
-
result.addException(req.baseUrl, 'registerWithPassword', ex);
|
72
|
-
return handleResponse(req, res, result);
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
|
-
async loginWithPassword(req: express.Request, res: express.Response) {
|
77
|
-
const result = res.locals.result;
|
78
|
-
try {
|
79
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'loginWithPassword', 'Started');
|
80
|
-
|
81
|
-
const { email, password } = req.body;
|
82
|
-
|
83
|
-
// Validate required fields
|
84
|
-
if (!email || !password) {
|
85
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
86
|
-
result.Errors.push('Email and password are required');
|
87
|
-
return handleResponse(req, res, result);
|
88
|
-
}
|
89
|
-
|
90
|
-
const authHelper = new AuthHelper(result);
|
91
|
-
const ipAddress = req.ip || req.connection.remoteAddress || '';
|
92
|
-
const userAgent = req.get('User-Agent') || '';
|
93
|
-
|
94
|
-
const serviceResult = await authHelper.loginWithPassword(email, password, ipAddress, userAgent);
|
95
|
-
|
96
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'loginWithPassword', 'Finished');
|
97
|
-
return handleResponse(req, res, serviceResult);
|
98
|
-
} catch (ex) {
|
99
|
-
result.addException(req.baseUrl, 'loginWithPassword', ex);
|
100
|
-
return handleResponse(req, res, result);
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
// Firebase Authentication
|
105
|
-
async authenticateWithFirebase(req: express.Request, res: express.Response) {
|
106
|
-
const result = res.locals.result;
|
107
|
-
try {
|
108
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'authenticateWithFirebase', 'Started');
|
109
|
-
|
110
|
-
const { firebase_token } = req.body;
|
111
|
-
|
112
|
-
if (!firebase_token) {
|
113
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
114
|
-
result.Errors.push('Firebase token is required');
|
115
|
-
return handleResponse(req, res, result);
|
116
|
-
}
|
117
|
-
|
118
|
-
const authHelper = new AuthHelper(result);
|
119
|
-
const ipAddress = req.ip || req.connection.remoteAddress || '';
|
120
|
-
const userAgent = req.get('User-Agent') || '';
|
121
|
-
|
122
|
-
const serviceResult = await authHelper.authenticateWithFirebase(firebase_token, ipAddress, userAgent);
|
123
|
-
|
124
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'authenticateWithFirebase', 'Finished');
|
125
|
-
return handleResponse(req, res, serviceResult);
|
126
|
-
} catch (ex) {
|
127
|
-
result.addException(req.baseUrl, 'authenticateWithFirebase', ex);
|
128
|
-
return handleResponse(req, res, result);
|
129
|
-
}
|
130
|
-
}
|
131
|
-
|
132
|
-
// OAuth Authentication
|
133
|
-
async authenticateWithOAuth(req: express.Request, res: express.Response) {
|
134
|
-
const result = res.locals.result;
|
135
|
-
try {
|
136
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'authenticateWithOAuth', 'Started');
|
137
|
-
|
138
|
-
const { provider, access_token } = req.body;
|
139
|
-
|
140
|
-
if (!provider || !access_token) {
|
141
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
142
|
-
result.Errors.push('Provider and access token are required');
|
143
|
-
return handleResponse(req, res, result);
|
144
|
-
}
|
145
|
-
|
146
|
-
const authHelper = new AuthHelper(result);
|
147
|
-
const ipAddress = req.ip || req.connection.remoteAddress || '';
|
148
|
-
const userAgent = req.get('User-Agent') || '';
|
149
|
-
|
150
|
-
const serviceResult = await authHelper.authenticateWithOAuth(provider, access_token, ipAddress, userAgent);
|
151
|
-
|
152
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'authenticateWithOAuth', 'Finished');
|
153
|
-
return handleResponse(req, res, serviceResult);
|
154
|
-
} catch (ex) {
|
155
|
-
result.addException(req.baseUrl, 'authenticateWithOAuth', ex);
|
156
|
-
return handleResponse(req, res, result);
|
157
|
-
}
|
158
|
-
}
|
159
|
-
|
160
|
-
// SMS OTP Authentication
|
161
|
-
async sendSMSOTP(req: express.Request, res: express.Response) {
|
162
|
-
const result = res.locals.result;
|
163
|
-
try {
|
164
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'sendSMSOTP', 'Started');
|
165
|
-
|
166
|
-
const { phone, purpose } = req.body;
|
167
|
-
|
168
|
-
if (!phone || !purpose) {
|
169
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
170
|
-
result.Errors.push('Phone number and purpose are required');
|
171
|
-
return handleResponse(req, res, result);
|
172
|
-
}
|
173
|
-
|
174
|
-
const authHelper = new AuthHelper(result);
|
175
|
-
const serviceResult = await authHelper.sendSMSOTP(phone, purpose);
|
176
|
-
|
177
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'sendSMSOTP', 'Finished');
|
178
|
-
return handleResponse(req, res, serviceResult);
|
179
|
-
} catch (ex) {
|
180
|
-
result.addException(req.baseUrl, 'sendSMSOTP', ex);
|
181
|
-
return handleResponse(req, res, result);
|
182
|
-
}
|
183
|
-
}
|
184
|
-
|
185
|
-
async verifySMSOTP(req: express.Request, res: express.Response) {
|
186
|
-
const result = res.locals.result;
|
187
|
-
try {
|
188
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'verifySMSOTP', 'Started');
|
189
|
-
|
190
|
-
const { phone, otp } = req.body;
|
191
|
-
|
192
|
-
if (!phone || !otp) {
|
193
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
194
|
-
result.Errors.push('Phone number and OTP are required');
|
195
|
-
return handleResponse(req, res, result);
|
196
|
-
}
|
197
|
-
|
198
|
-
const authHelper = new AuthHelper(result);
|
199
|
-
const ipAddress = req.ip || req.connection.remoteAddress || '';
|
200
|
-
const userAgent = req.get('User-Agent') || '';
|
201
|
-
|
202
|
-
const serviceResult = await authHelper.verifySMSOTP(phone, otp, ipAddress, userAgent);
|
203
|
-
|
204
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'verifySMSOTP', 'Finished');
|
205
|
-
return handleResponse(req, res, serviceResult);
|
206
|
-
} catch (ex) {
|
207
|
-
result.addException(req.baseUrl, 'verifySMSOTP', ex);
|
208
|
-
return handleResponse(req, res, result);
|
209
|
-
}
|
210
|
-
}
|
211
|
-
|
212
|
-
// Email OTP Authentication
|
213
|
-
async sendEmailOTP(req: express.Request, res: express.Response) {
|
214
|
-
const result = res.locals.result;
|
215
|
-
try {
|
216
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'sendEmailOTP', 'Started');
|
217
|
-
|
218
|
-
const { email, purpose } = req.body;
|
219
|
-
|
220
|
-
if (!email || !purpose) {
|
221
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
222
|
-
result.Errors.push('Email and purpose are required');
|
223
|
-
return handleResponse(req, res, result);
|
224
|
-
}
|
225
|
-
|
226
|
-
const authHelper = new AuthHelper(result);
|
227
|
-
const serviceResult = await authHelper.sendEmailOTP(email, purpose);
|
228
|
-
|
229
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'sendEmailOTP', 'Finished');
|
230
|
-
return handleResponse(req, res, serviceResult);
|
231
|
-
} catch (ex) {
|
232
|
-
result.addException(req.baseUrl, 'sendEmailOTP', ex);
|
233
|
-
return handleResponse(req, res, result);
|
234
|
-
}
|
235
|
-
}
|
236
|
-
|
237
|
-
// Session Management
|
238
|
-
async verifySession(req: express.Request, res: express.Response) {
|
239
|
-
const result = res.locals.result;
|
240
|
-
try {
|
241
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'verifySession', 'Started');
|
242
|
-
|
243
|
-
const { session_id, token } = req.body;
|
244
|
-
|
245
|
-
if (!session_id || !token) {
|
246
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
247
|
-
result.Errors.push('Session ID and token are required');
|
248
|
-
return handleResponse(req, res, result);
|
249
|
-
}
|
250
|
-
|
251
|
-
const authHelper = new AuthHelper(result);
|
252
|
-
const serviceResult = await authHelper.verifySession(session_id, token);
|
253
|
-
|
254
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'verifySession', 'Finished');
|
255
|
-
return handleResponse(req, res, serviceResult);
|
256
|
-
} catch (ex) {
|
257
|
-
result.addException(req.baseUrl, 'verifySession', ex);
|
258
|
-
return handleResponse(req, res, result);
|
259
|
-
}
|
260
|
-
}
|
261
|
-
|
262
|
-
async logout(req: express.Request, res: express.Response) {
|
263
|
-
const result = res.locals.result;
|
264
|
-
try {
|
265
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'logout', 'Started');
|
266
|
-
|
267
|
-
const { session_id } = req.body;
|
268
|
-
|
269
|
-
if (!session_id) {
|
270
|
-
result.Status = ResponseCode.MissingRequiredFields;
|
271
|
-
result.Errors.push('Session ID is required');
|
272
|
-
return handleResponse(req, res, result);
|
273
|
-
}
|
274
|
-
|
275
|
-
const authHelper = new AuthHelper(result);
|
276
|
-
const serviceResult = await authHelper.logout(session_id);
|
277
|
-
|
278
|
-
result.addMessage(AuditMessageType.info, req.baseUrl, 'logout', 'Finished');
|
279
|
-
return handleResponse(req, res, serviceResult);
|
280
|
-
} catch (ex) {
|
281
|
-
result.addException(req.baseUrl, 'logout', ex);
|
282
|
-
return handleResponse(req, res, result);
|
283
|
-
}
|
284
|
-
}
|
285
|
-
}
|
286
|
-
export const authRouter = new AuthRoutes().Router;
|
@@ -1,92 +0,0 @@
|
|
1
|
-
import * as express from "express";
|
2
|
-
import { accountRouter } from "./account-routes";
|
3
|
-
import { authRouter } from "./auth-routes";
|
4
|
-
import { AuditService } from "../services/audit-service";
|
5
|
-
import { Result } from "../helpers/result";
|
6
|
-
import { AuditMessageType, ResponseCode } from "../helpers/enums";
|
7
|
-
import { AuthHelper } from "../helpers/auth"; // adjust import path as needed
|
8
|
-
import handleResponse from "../helpers/handle-response";
|
9
|
-
|
10
|
-
const cors = require("cors");
|
11
|
-
|
12
|
-
const _accRoutePerfix = "account";
|
13
|
-
const _authRoutePerfix = "auth";
|
14
|
-
|
15
|
-
const corsOptions = {
|
16
|
-
origin: "*", // adjust for production
|
17
|
-
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
|
18
|
-
allowedHeaders: ["Authorization", "Content-Type"],
|
19
|
-
};
|
20
|
-
|
21
|
-
/**
|
22
|
-
* Middleware to inject a Result object into every request
|
23
|
-
*/
|
24
|
-
const injectResult = (req, res, next) => {
|
25
|
-
const requestIdentifier = req.header("request-identifier") || new Date().getTime().toString();
|
26
|
-
const result = new Result(null, ResponseCode.Incompelete, [], [], requestIdentifier);
|
27
|
-
res.locals["result"] = result;
|
28
|
-
next();
|
29
|
-
};
|
30
|
-
|
31
|
-
/**
|
32
|
-
* Basic authentication middleware for secured routes
|
33
|
-
*/
|
34
|
-
const authChecker = async (req, res, next) => {
|
35
|
-
const result = res.locals["result"];
|
36
|
-
try {
|
37
|
-
const authorization = req.headers["authorization"];
|
38
|
-
if (!authorization) {
|
39
|
-
result.Status = ResponseCode.Unauthorized;
|
40
|
-
return handleResponse(req, res, result);
|
41
|
-
}
|
42
|
-
|
43
|
-
const authHelper = new AuthHelper(result);
|
44
|
-
const verifyTokenResult = await authHelper.VerifyToken(authorization);
|
45
|
-
if (verifyTokenResult.Status !== ResponseCode.Ok) {
|
46
|
-
result.Status = ResponseCode.Unauthorized;
|
47
|
-
return handleResponse(req, res, result);
|
48
|
-
}
|
49
|
-
|
50
|
-
// Attach user data to result
|
51
|
-
result.user = verifyTokenResult.Data;
|
52
|
-
next();
|
53
|
-
} catch (ex) {
|
54
|
-
console.error("Auth error:", ex.message);
|
55
|
-
result.Status = ResponseCode.Error;
|
56
|
-
return handleResponse(req, res, result);
|
57
|
-
}
|
58
|
-
};
|
59
|
-
|
60
|
-
export class Routes {
|
61
|
-
init(server: express.Application) {
|
62
|
-
const auditService = new AuditService();
|
63
|
-
|
64
|
-
server.use(cors(corsOptions));
|
65
|
-
|
66
|
-
// Inject result object into every request
|
67
|
-
server.use(injectResult);
|
68
|
-
|
69
|
-
// Health check route (public)
|
70
|
-
server.get("/", (req, res) => {
|
71
|
-
const result = res.locals["result"];
|
72
|
-
result.Status = ResponseCode.Ok;
|
73
|
-
result.Data = "Welcome to Tactic API Template";
|
74
|
-
auditService.AddAuditSingle(AuditMessageType.info, "Routes Main", "Health Check", result.RequrestIdentifier, "API health check route called");
|
75
|
-
res.send(result);
|
76
|
-
});
|
77
|
-
|
78
|
-
// Audit check route (public)
|
79
|
-
server.get("/audit/health", (req, res) => {
|
80
|
-
const result = res.locals["result"];
|
81
|
-
result.Status = ResponseCode.Ok;
|
82
|
-
result.Data = "Audit module is up";
|
83
|
-
res.send(result);
|
84
|
-
});
|
85
|
-
|
86
|
-
// Account routes (secured)
|
87
|
-
server.use(`/${_accRoutePerfix}/`, accountRouter);
|
88
|
-
|
89
|
-
// Auth routes (public - no authentication required)
|
90
|
-
server.use(`/${_authRoutePerfix}/`, authRouter);
|
91
|
-
}
|
92
|
-
}
|
@@ -1,36 +0,0 @@
|
|
1
|
-
import { ObjectId } from 'bson';
|
2
|
-
import * as mongoose from 'mongoose';
|
3
|
-
import { v4 as uuidv4 } from 'uuid';
|
4
|
-
import { IAudit } from '../entities/audit';
|
5
|
-
const auditSchema = new mongoose.Schema(
|
6
|
-
{
|
7
|
-
type: {
|
8
|
-
type: String
|
9
|
-
},
|
10
|
-
auditTime: {
|
11
|
-
type: Date
|
12
|
-
},
|
13
|
-
className: {
|
14
|
-
type: String
|
15
|
-
},
|
16
|
-
methodName: {
|
17
|
-
type: String
|
18
|
-
},
|
19
|
-
requestIdentifier: {
|
20
|
-
type: String
|
21
|
-
},
|
22
|
-
message: {
|
23
|
-
type: String
|
24
|
-
},
|
25
|
-
additionalInfo: {
|
26
|
-
type: JSON
|
27
|
-
},
|
28
|
-
updatedAt: {
|
29
|
-
type: Date,
|
30
|
-
default: new Date()
|
31
|
-
}
|
32
|
-
},
|
33
|
-
{ timestamps: true, suppressReservedKeysWarning: true },
|
34
|
-
);
|
35
|
-
|
36
|
-
export const AuditEntity = mongoose.model<IAudit>('audit', auditSchema);
|