@resolveio/server-lib 22.2.21 → 22.2.23
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/collections/customer-portal-password.collection.d.ts +3 -0
- package/collections/customer-portal-password.collection.js +75 -0
- package/collections/customer-portal-password.collection.js.map +1 -0
- package/managers/mongo.manager.js +11 -4
- package/managers/mongo.manager.js.map +1 -1
- package/managers/openai-usage-ledger.manager.d.ts +1 -1
- package/managers/openai-usage-ledger.manager.js +4 -3
- package/managers/openai-usage-ledger.manager.js.map +1 -1
- package/methods/accounts.js +85 -2
- package/methods/accounts.js.map +1 -1
- package/methods/ai-terminal.js +10 -17
- package/methods/ai-terminal.js.map +1 -1
- package/methods/mongo-explorer.js +2 -2
- package/methods/mongo-explorer.js.map +1 -1
- package/methods/report-builder.js +11 -13
- package/methods/report-builder.js.map +1 -1
- package/methods.ts +5 -2
- package/models/customer-portal-password.model.d.ts +11 -0
- package/models/customer-portal-password.model.js +4 -0
- package/models/customer-portal-password.model.js.map +1 -0
- package/package.json +1 -1
- package/public_api.d.ts +3 -0
- package/public_api.js +3 -0
- package/public_api.js.map +1 -1
- package/util/customer-portal-password.d.ts +13 -0
- package/util/customer-portal-password.js +209 -0
- package/util/customer-portal-password.js.map +1 -0
package/methods.ts
CHANGED
|
@@ -108,6 +108,9 @@ export function SERVER_METHODS(resolveioServer) {
|
|
|
108
108
|
generatePDFNoPageNumber: (html, fileName, orientation = 'portrait', fontSize = '12px', upload = false, uploadFileOrder = -1, uploadFileType = '', cb?: Function): Promise<any> => {
|
|
109
109
|
return resolveioServer.call('generatePDFNoPageNumber', html, fileName, orientation, fontSize, upload, uploadFileOrder, uploadFileType, cb);
|
|
110
110
|
},
|
|
111
|
+
getCustomerPortalUserPassword: (userId: string, cb?: Function): Promise<any> => {
|
|
112
|
+
return resolveioServer.call('getCustomerPortalUserPassword', userId, cb);
|
|
113
|
+
},
|
|
111
114
|
getDataURIfromURL: (url: string, cb?: Function): Promise<any> => {
|
|
112
115
|
return resolveioServer.call('getDataURIfromURL', url, cb);
|
|
113
116
|
},
|
|
@@ -253,10 +256,10 @@ export function SERVER_METHODS(resolveioServer) {
|
|
|
253
256
|
return resolveioServer.call('superAdminDeploySlowQueryLog', logId, cb);
|
|
254
257
|
},
|
|
255
258
|
superAdminListAutoFixLogs: (payload: Record<string, any> = {}, cb?: Function): Promise<any> => {
|
|
256
|
-
return resolveioServer.call('superAdminListAutoFixLogs', payload,
|
|
259
|
+
return resolveioServer.call('superAdminListAutoFixLogs', payload, cb);
|
|
257
260
|
},
|
|
258
261
|
superAdminListSlowQueryLogs: (payload: Record<string, any> = {}, cb?: Function): Promise<any> => {
|
|
259
|
-
return resolveioServer.call('superAdminListSlowQueryLogs', payload,
|
|
262
|
+
return resolveioServer.call('superAdminListSlowQueryLogs', payload, cb);
|
|
260
263
|
},
|
|
261
264
|
superAdminRunAutoFixLog: (logId: string, cb?: Function): Promise<any> => {
|
|
262
265
|
return resolveioServer.call('superAdminRunAutoFixLog', logId, cb);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CollectionDocument } from './collection-document.model';
|
|
2
|
+
export interface CustomerPortalPasswordModel extends CollectionDocument {
|
|
3
|
+
id_user: string;
|
|
4
|
+
cipher_text: string;
|
|
5
|
+
iv: string;
|
|
6
|
+
auth_tag: string;
|
|
7
|
+
key_version: number;
|
|
8
|
+
last_set_at: Date;
|
|
9
|
+
updated_by_user_id?: string;
|
|
10
|
+
updated_by_user?: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/models/customer-portal-password.model.ts"],"names":[],"mappings":"","file":"customer-portal-password.model.js","sourcesContent":["import { CollectionDocument } from './collection-document.model';\n\nexport interface CustomerPortalPasswordModel extends CollectionDocument {\n\tid_user: string;\n\tcipher_text: string;\n\tiv: string;\n\tauth_tag: string;\n\tkey_version: number;\n\tlast_set_at: Date;\n\tupdated_by_user_id?: string;\n\tupdated_by_user?: string;\n}\n"]}
|
package/package.json
CHANGED
package/public_api.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './collections/ai-terminal-issue-report.collection';
|
|
|
4
4
|
export * from './collections/ai-terminal-conversation.collection';
|
|
5
5
|
export * from './collections/ai-terminal-message.collection';
|
|
6
6
|
export * from './collections/counter.collection';
|
|
7
|
+
export * from './collections/customer-portal-password.collection';
|
|
7
8
|
export * from './collections/customer-notification.collection';
|
|
8
9
|
export * from './collections/communication-metric.collection';
|
|
9
10
|
export * from './collections/cron-job-history.collection';
|
|
@@ -43,6 +44,7 @@ export * from './models/billing-logged-in-users.model';
|
|
|
43
44
|
export * from './models/collection-document.model';
|
|
44
45
|
export * from './models/communication-metric.model';
|
|
45
46
|
export * from './models/counter.model';
|
|
47
|
+
export * from './models/customer-portal-password.model';
|
|
46
48
|
export * from './models/customer-notification.model';
|
|
47
49
|
export * from './models/cron-job-history.model';
|
|
48
50
|
export * from './models/cron-job.model';
|
|
@@ -83,4 +85,5 @@ export * from './resolveio-server-app';
|
|
|
83
85
|
export * from './services/openai-client';
|
|
84
86
|
export * from './services/codex-client';
|
|
85
87
|
export * from './util/common';
|
|
88
|
+
export * from './util/customer-portal-password';
|
|
86
89
|
export * from './util/tokenizer';
|
package/public_api.js
CHANGED
|
@@ -20,6 +20,7 @@ __exportStar(require("./collections/ai-terminal-issue-report.collection"), expor
|
|
|
20
20
|
__exportStar(require("./collections/ai-terminal-conversation.collection"), exports);
|
|
21
21
|
__exportStar(require("./collections/ai-terminal-message.collection"), exports);
|
|
22
22
|
__exportStar(require("./collections/counter.collection"), exports);
|
|
23
|
+
__exportStar(require("./collections/customer-portal-password.collection"), exports);
|
|
23
24
|
__exportStar(require("./collections/customer-notification.collection"), exports);
|
|
24
25
|
__exportStar(require("./collections/communication-metric.collection"), exports);
|
|
25
26
|
__exportStar(require("./collections/cron-job-history.collection"), exports);
|
|
@@ -59,6 +60,7 @@ __exportStar(require("./models/billing-logged-in-users.model"), exports);
|
|
|
59
60
|
__exportStar(require("./models/collection-document.model"), exports);
|
|
60
61
|
__exportStar(require("./models/communication-metric.model"), exports);
|
|
61
62
|
__exportStar(require("./models/counter.model"), exports);
|
|
63
|
+
__exportStar(require("./models/customer-portal-password.model"), exports);
|
|
62
64
|
__exportStar(require("./models/customer-notification.model"), exports);
|
|
63
65
|
__exportStar(require("./models/cron-job-history.model"), exports);
|
|
64
66
|
__exportStar(require("./models/cron-job.model"), exports);
|
|
@@ -99,6 +101,7 @@ __exportStar(require("./resolveio-server-app"), exports);
|
|
|
99
101
|
__exportStar(require("./services/openai-client"), exports);
|
|
100
102
|
__exportStar(require("./services/codex-client"), exports);
|
|
101
103
|
__exportStar(require("./util/common"), exports);
|
|
104
|
+
__exportStar(require("./util/customer-portal-password"), exports);
|
|
102
105
|
__exportStar(require("./util/tokenizer"), exports);
|
|
103
106
|
|
|
104
107
|
//# sourceMappingURL=public_api.js.map
|
package/public_api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/public_api.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sEAAoD;AACpD,uEAAqD;AACrD,oFAAkE;AAClE,oFAAkE;AAClE,+EAA6D;AAC7D,mEAAiD;AACjD,iFAA+D;AAC/D,gFAA8D;AAC9D,4EAA0D;AAC1D,oEAAkD;AAClD,yEAAuD;AACvD,0EAAwD;AACxD,gEAA8C;AAC9C,uEAAqD;AACrD,gEAA8C;AAC9C,8EAA4D;AAC5D,4EAA0D;AAC1D,+DAA6C;AAC7C,2EAAyD;AACzD,uEAAqD;AACrD,4EAA0D;AAC1D,0EAAwD;AACxD,yEAAuD;AACvD,wEAAsD;AACtD,+EAA6D;AAC7D,kFAAgE;AAChE,iFAA+D;AAC/D,sEAAoD;AACpD,sEAAoD;AACpD,gEAA8C;AAC9C,2DAAyC;AACzC,oEAAkD;AAClD,yEAAuD;AACvD,gEAA8C;AAC9C,mFAAiE;AACjE,0EAAwD;AACxD,4DAA0C;AAC1C,6DAA2C;AAC3C,0EAAwD;AACxD,0EAAwD;AACxD,qEAAmD;AACnD,yEAAuD;AACvD,qEAAmD;AACnD,sEAAoD;AACpD,yDAAuC;AACvC,uEAAqD;AACrD,kEAAgD;AAChD,0DAAwC;AACxC,wDAAsC;AACtC,+DAA6C;AAC7C,gEAA8C;AAC9C,sDAAoC;AACpC,6DAA2C;AAC3C,sDAAoC;AACpC,oEAAkD;AAClD,kEAAgD;AAChD,qDAAmC;AACnC,iEAA+C;AAC/C,iEAA+C;AAC/C,wDAAsC;AACtC,6DAA2C;AAC3C,gEAA8C;AAC9C,+DAA6C;AAC7C,8DAA4C;AAC5C,qEAAmD;AACnD,4DAA0C;AAC1C,4DAA0C;AAC1C,wEAAsD;AACtD,uEAAqD;AACrD,gEAA8C;AAC9C,mEAAiD;AACjD,gEAA8C;AAC9C,8DAA4C;AAC5C,gEAA8C;AAC9C,4DAA0C;AAC1C,4DAA0C;AAC1C,sDAAoC;AACpC,uDAAqC;AACrC,4DAA0C;AAC1C,yEAAuD;AACvD,0EAAwD;AACxD,yDAAuC;AACvC,2DAAyC;AACzC,0DAAwC;AACxC,gDAA8B;AAC9B,mDAAiC","file":"public_api.js","sourcesContent":["export * from './collections/app-status.collection';\nexport * from './collections/app-setting.collection';\nexport * from './collections/ai-terminal-issue-report.collection';\nexport * from './collections/ai-terminal-conversation.collection';\nexport * from './collections/ai-terminal-message.collection';\nexport * from './collections/counter.collection';\nexport * from './collections/customer-notification.collection';\nexport * from './collections/communication-metric.collection';\nexport * from './collections/cron-job-history.collection';\nexport * from './collections/cron-job.collection';\nexport * from './collections/email-history.collection';\nexport * from './collections/email-verified.collection';\nexport * from './collections/file.collection';\nexport * from './collections/flag-update.collection';\nexport * from './collections/flag.collection';\nexport * from './collections/log-method-latency.collection';\nexport * from './collections/log-subscription.collection';\nexport * from './collections/log.collection';\nexport * from './collections/logged-in-users.collection';\nexport * from './collections/monitor-cpu.collection';\nexport * from './collections/monitor-function.collection';\nexport * from './collections/monitor-memory.collection';\nexport * from './collections/monitor-mongo.collection';\nexport * from './collections/notification.collection';\nexport * from './collections/openai-usage-ledger.collection';\nexport * from './collections/report-builder-library.collection';\nexport * from './collections/report-builder-report.collection';\nexport * from './collections/user-group.collection';\nexport * from './collections/user-guide.collection';\nexport * from './collections/user.collection';\nexport * from './managers/mongo.manager';\nexport * from './managers/error-auto-fix.manager';\nexport * from './managers/slow-query-verifier.manager';\nexport * from './managers/slow-query.manager';\nexport * from './managers/customer-notification-content.manager';\nexport * from './managers/diagnostic-manager-bootstrap';\nexport * from './models/app-status.model';\nexport * from './models/app-setting.model';\nexport * from './models/ai-terminal-issue-report.model';\nexport * from './models/ai-terminal-conversation.model';\nexport * from './models/ai-terminal-message.model';\nexport * from './models/billing-logged-in-users.model';\nexport * from './models/collection-document.model';\nexport * from './models/communication-metric.model';\nexport * from './models/counter.model';\nexport * from './models/customer-notification.model';\nexport * from './models/cron-job-history.model';\nexport * from './models/cron-job.model';\nexport * from './models/dialog.model';\nexport * from './models/email-history.model';\nexport * from './models/email-verified.model';\nexport * from './models/file.model';\nexport * from './models/flag-update.model';\nexport * from './models/flag.model';\nexport * from './models/log-method-latency.model';\nexport * from './models/log-subscription.model';\nexport * from './models/log.model';\nexport * from './models/logged-in-users.model';\nexport * from './models/method-response.model';\nexport * from './models/method.model';\nexport * from './models/monitor-cpu.model';\nexport * from './models/monitor-memory.model';\nexport * from './models/monitor-mongo.model';\nexport * from './models/notification.model';\nexport * from './models/openai-usage-ledger.model';\nexport * from './models/pagination.model';\nexport * from './models/permission.model';\nexport * from './models/report-builder-library.model';\nexport * from './models/report-builder-report.model';\nexport * from './models/report-builder.model';\nexport * from './models/select-data-label.model';\nexport * from './models/server-message.model';\nexport * from './models/subscription.model';\nexport * from './models/support-ticket.model';\nexport * from './models/user-group.model';\nexport * from './models/user-guide.model';\nexport * from './models/user.model';\nexport * from './types/error-report';\nexport * from './types/slow-query-report';\nexport * from './managers/openai-usage-ledger.manager';\nexport * from './managers/communication-metric.manager';\nexport * from './resolveio-server-app';\nexport * from './services/openai-client';\nexport * from './services/codex-client';\nexport * from './util/common';\nexport * from './util/tokenizer';\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/public_api.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sEAAoD;AACpD,uEAAqD;AACrD,oFAAkE;AAClE,oFAAkE;AAClE,+EAA6D;AAC7D,mEAAiD;AACjD,oFAAkE;AAClE,iFAA+D;AAC/D,gFAA8D;AAC9D,4EAA0D;AAC1D,oEAAkD;AAClD,yEAAuD;AACvD,0EAAwD;AACxD,gEAA8C;AAC9C,uEAAqD;AACrD,gEAA8C;AAC9C,8EAA4D;AAC5D,4EAA0D;AAC1D,+DAA6C;AAC7C,2EAAyD;AACzD,uEAAqD;AACrD,4EAA0D;AAC1D,0EAAwD;AACxD,yEAAuD;AACvD,wEAAsD;AACtD,+EAA6D;AAC7D,kFAAgE;AAChE,iFAA+D;AAC/D,sEAAoD;AACpD,sEAAoD;AACpD,gEAA8C;AAC9C,2DAAyC;AACzC,oEAAkD;AAClD,yEAAuD;AACvD,gEAA8C;AAC9C,mFAAiE;AACjE,0EAAwD;AACxD,4DAA0C;AAC1C,6DAA2C;AAC3C,0EAAwD;AACxD,0EAAwD;AACxD,qEAAmD;AACnD,yEAAuD;AACvD,qEAAmD;AACnD,sEAAoD;AACpD,yDAAuC;AACvC,0EAAwD;AACxD,uEAAqD;AACrD,kEAAgD;AAChD,0DAAwC;AACxC,wDAAsC;AACtC,+DAA6C;AAC7C,gEAA8C;AAC9C,sDAAoC;AACpC,6DAA2C;AAC3C,sDAAoC;AACpC,oEAAkD;AAClD,kEAAgD;AAChD,qDAAmC;AACnC,iEAA+C;AAC/C,iEAA+C;AAC/C,wDAAsC;AACtC,6DAA2C;AAC3C,gEAA8C;AAC9C,+DAA6C;AAC7C,8DAA4C;AAC5C,qEAAmD;AACnD,4DAA0C;AAC1C,4DAA0C;AAC1C,wEAAsD;AACtD,uEAAqD;AACrD,gEAA8C;AAC9C,mEAAiD;AACjD,gEAA8C;AAC9C,8DAA4C;AAC5C,gEAA8C;AAC9C,4DAA0C;AAC1C,4DAA0C;AAC1C,sDAAoC;AACpC,uDAAqC;AACrC,4DAA0C;AAC1C,yEAAuD;AACvD,0EAAwD;AACxD,yDAAuC;AACvC,2DAAyC;AACzC,0DAAwC;AACxC,gDAA8B;AAC9B,kEAAgD;AAChD,mDAAiC","file":"public_api.js","sourcesContent":["export * from './collections/app-status.collection';\nexport * from './collections/app-setting.collection';\nexport * from './collections/ai-terminal-issue-report.collection';\nexport * from './collections/ai-terminal-conversation.collection';\nexport * from './collections/ai-terminal-message.collection';\nexport * from './collections/counter.collection';\nexport * from './collections/customer-portal-password.collection';\nexport * from './collections/customer-notification.collection';\nexport * from './collections/communication-metric.collection';\nexport * from './collections/cron-job-history.collection';\nexport * from './collections/cron-job.collection';\nexport * from './collections/email-history.collection';\nexport * from './collections/email-verified.collection';\nexport * from './collections/file.collection';\nexport * from './collections/flag-update.collection';\nexport * from './collections/flag.collection';\nexport * from './collections/log-method-latency.collection';\nexport * from './collections/log-subscription.collection';\nexport * from './collections/log.collection';\nexport * from './collections/logged-in-users.collection';\nexport * from './collections/monitor-cpu.collection';\nexport * from './collections/monitor-function.collection';\nexport * from './collections/monitor-memory.collection';\nexport * from './collections/monitor-mongo.collection';\nexport * from './collections/notification.collection';\nexport * from './collections/openai-usage-ledger.collection';\nexport * from './collections/report-builder-library.collection';\nexport * from './collections/report-builder-report.collection';\nexport * from './collections/user-group.collection';\nexport * from './collections/user-guide.collection';\nexport * from './collections/user.collection';\nexport * from './managers/mongo.manager';\nexport * from './managers/error-auto-fix.manager';\nexport * from './managers/slow-query-verifier.manager';\nexport * from './managers/slow-query.manager';\nexport * from './managers/customer-notification-content.manager';\nexport * from './managers/diagnostic-manager-bootstrap';\nexport * from './models/app-status.model';\nexport * from './models/app-setting.model';\nexport * from './models/ai-terminal-issue-report.model';\nexport * from './models/ai-terminal-conversation.model';\nexport * from './models/ai-terminal-message.model';\nexport * from './models/billing-logged-in-users.model';\nexport * from './models/collection-document.model';\nexport * from './models/communication-metric.model';\nexport * from './models/counter.model';\nexport * from './models/customer-portal-password.model';\nexport * from './models/customer-notification.model';\nexport * from './models/cron-job-history.model';\nexport * from './models/cron-job.model';\nexport * from './models/dialog.model';\nexport * from './models/email-history.model';\nexport * from './models/email-verified.model';\nexport * from './models/file.model';\nexport * from './models/flag-update.model';\nexport * from './models/flag.model';\nexport * from './models/log-method-latency.model';\nexport * from './models/log-subscription.model';\nexport * from './models/log.model';\nexport * from './models/logged-in-users.model';\nexport * from './models/method-response.model';\nexport * from './models/method.model';\nexport * from './models/monitor-cpu.model';\nexport * from './models/monitor-memory.model';\nexport * from './models/monitor-mongo.model';\nexport * from './models/notification.model';\nexport * from './models/openai-usage-ledger.model';\nexport * from './models/pagination.model';\nexport * from './models/permission.model';\nexport * from './models/report-builder-library.model';\nexport * from './models/report-builder-report.model';\nexport * from './models/report-builder.model';\nexport * from './models/select-data-label.model';\nexport * from './models/server-message.model';\nexport * from './models/subscription.model';\nexport * from './models/support-ticket.model';\nexport * from './models/user-group.model';\nexport * from './models/user-guide.model';\nexport * from './models/user.model';\nexport * from './types/error-report';\nexport * from './types/slow-query-report';\nexport * from './managers/openai-usage-ledger.manager';\nexport * from './managers/communication-metric.manager';\nexport * from './resolveio-server-app';\nexport * from './services/openai-client';\nexport * from './services/codex-client';\nexport * from './util/common';\nexport * from './util/customer-portal-password';\nexport * from './util/tokenizer';\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { UserModel } from '../models/user.model';
|
|
2
|
+
interface PasswordRecordMeta {
|
|
3
|
+
updatedByUserId?: string;
|
|
4
|
+
updatedByUser?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function isCustomerPortalUser(user: UserModel | any): boolean;
|
|
7
|
+
export declare function saveCustomerPortalPassword(user: UserModel | any, password: string, meta?: PasswordRecordMeta): Promise<void>;
|
|
8
|
+
export declare function clearCustomerPortalPassword(userId: string): Promise<void>;
|
|
9
|
+
export declare function getDecryptedCustomerPortalPassword(userId: string): Promise<{
|
|
10
|
+
password: string;
|
|
11
|
+
lastSetAt?: Date;
|
|
12
|
+
}>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.isCustomerPortalUser = isCustomerPortalUser;
|
|
40
|
+
exports.saveCustomerPortalPassword = saveCustomerPortalPassword;
|
|
41
|
+
exports.clearCustomerPortalPassword = clearCustomerPortalPassword;
|
|
42
|
+
exports.getDecryptedCustomerPortalPassword = getDecryptedCustomerPortalPassword;
|
|
43
|
+
var customer_portal_password_collection_1 = require("../collections/customer-portal-password.collection");
|
|
44
|
+
var resolveio_server_app_1 = require("../resolveio-server-app");
|
|
45
|
+
var crypto = require('crypto');
|
|
46
|
+
var ALGORITHM = 'aes-256-gcm';
|
|
47
|
+
var ENCRYPTION_KEY_VERSION = 1;
|
|
48
|
+
var IV_LENGTH_BYTES = 12;
|
|
49
|
+
function isCustomerPortalUser(user) {
|
|
50
|
+
var _a;
|
|
51
|
+
if (!user || typeof user !== 'object') {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
var other = user.other || {};
|
|
55
|
+
if (other.id_customer) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
if (Array.isArray(other.customers) && other.customers.length > 0) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
var groups = Array.isArray((_a = user === null || user === void 0 ? void 0 : user.roles) === null || _a === void 0 ? void 0 : _a.groups) ? user.roles.groups : [];
|
|
62
|
+
if (groups.some(function (group) {
|
|
63
|
+
if (!group || typeof group.name !== 'string') {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
var normalized = group.name.trim().toLowerCase();
|
|
67
|
+
return normalized === 'customer portal' || normalized === 'customer-portal';
|
|
68
|
+
})) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
function saveCustomerPortalPassword(user, password, meta) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
75
|
+
var payload, setData;
|
|
76
|
+
return __generator(this, function (_a) {
|
|
77
|
+
switch (_a.label) {
|
|
78
|
+
case 0:
|
|
79
|
+
if (!(user === null || user === void 0 ? void 0 : user._id)) {
|
|
80
|
+
return [2 /*return*/];
|
|
81
|
+
}
|
|
82
|
+
if (!customer_portal_password_collection_1.CustomerPortalPasswords) {
|
|
83
|
+
return [2 /*return*/];
|
|
84
|
+
}
|
|
85
|
+
if (!!isCustomerPortalUser(user)) return [3 /*break*/, 2];
|
|
86
|
+
return [4 /*yield*/, clearCustomerPortalPassword(user._id)];
|
|
87
|
+
case 1:
|
|
88
|
+
_a.sent();
|
|
89
|
+
return [2 /*return*/];
|
|
90
|
+
case 2:
|
|
91
|
+
if (!(!password || typeof password !== 'string')) return [3 /*break*/, 4];
|
|
92
|
+
return [4 /*yield*/, clearCustomerPortalPassword(user._id)];
|
|
93
|
+
case 3:
|
|
94
|
+
_a.sent();
|
|
95
|
+
return [2 /*return*/];
|
|
96
|
+
case 4:
|
|
97
|
+
payload = encryptPassword(password);
|
|
98
|
+
setData = {
|
|
99
|
+
id_user: user._id,
|
|
100
|
+
cipher_text: payload.cipherText,
|
|
101
|
+
iv: payload.iv,
|
|
102
|
+
auth_tag: payload.authTag,
|
|
103
|
+
key_version: payload.keyVersion,
|
|
104
|
+
last_set_at: new Date()
|
|
105
|
+
};
|
|
106
|
+
if (meta === null || meta === void 0 ? void 0 : meta.updatedByUserId) {
|
|
107
|
+
setData.updated_by_user_id = meta.updatedByUserId;
|
|
108
|
+
}
|
|
109
|
+
if (meta === null || meta === void 0 ? void 0 : meta.updatedByUser) {
|
|
110
|
+
setData.updated_by_user = meta.updatedByUser;
|
|
111
|
+
}
|
|
112
|
+
return [4 /*yield*/, customer_portal_password_collection_1.CustomerPortalPasswords.updateOne({ id_user: user._id }, {
|
|
113
|
+
$set: setData
|
|
114
|
+
}, { upsert: true })];
|
|
115
|
+
case 5:
|
|
116
|
+
_a.sent();
|
|
117
|
+
return [2 /*return*/];
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function clearCustomerPortalPassword(userId) {
|
|
123
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
124
|
+
return __generator(this, function (_a) {
|
|
125
|
+
switch (_a.label) {
|
|
126
|
+
case 0:
|
|
127
|
+
if (!userId || !customer_portal_password_collection_1.CustomerPortalPasswords) {
|
|
128
|
+
return [2 /*return*/];
|
|
129
|
+
}
|
|
130
|
+
return [4 /*yield*/, customer_portal_password_collection_1.CustomerPortalPasswords.deleteOne({ id_user: userId })];
|
|
131
|
+
case 1:
|
|
132
|
+
_a.sent();
|
|
133
|
+
return [2 /*return*/];
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function getDecryptedCustomerPortalPassword(userId) {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
140
|
+
var record, password;
|
|
141
|
+
return __generator(this, function (_a) {
|
|
142
|
+
switch (_a.label) {
|
|
143
|
+
case 0:
|
|
144
|
+
if (!userId) {
|
|
145
|
+
throw new Error('Customer portal user id is required.');
|
|
146
|
+
}
|
|
147
|
+
if (!customer_portal_password_collection_1.CustomerPortalPasswords) {
|
|
148
|
+
throw new Error('Customer portal password store is not available.');
|
|
149
|
+
}
|
|
150
|
+
return [4 /*yield*/, customer_portal_password_collection_1.CustomerPortalPasswords.findOne({ id_user: userId })];
|
|
151
|
+
case 1:
|
|
152
|
+
record = _a.sent();
|
|
153
|
+
if (!record) {
|
|
154
|
+
throw new Error('No stored customer portal password is available for this user.');
|
|
155
|
+
}
|
|
156
|
+
password = decryptPassword({
|
|
157
|
+
cipherText: record.cipher_text,
|
|
158
|
+
iv: record.iv,
|
|
159
|
+
authTag: record.auth_tag,
|
|
160
|
+
keyVersion: record.key_version
|
|
161
|
+
});
|
|
162
|
+
return [2 /*return*/, {
|
|
163
|
+
password: password,
|
|
164
|
+
lastSetAt: record.last_set_at
|
|
165
|
+
}];
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function encryptPassword(plainText) {
|
|
171
|
+
var key = resolveEncryptionKey();
|
|
172
|
+
var ivBuffer = crypto.randomBytes(IV_LENGTH_BYTES);
|
|
173
|
+
var cipher = crypto.createCipheriv(ALGORITHM, key, ivBuffer);
|
|
174
|
+
var encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);
|
|
175
|
+
var authTag = cipher.getAuthTag();
|
|
176
|
+
return {
|
|
177
|
+
cipherText: encrypted.toString('base64'),
|
|
178
|
+
iv: ivBuffer.toString('base64'),
|
|
179
|
+
authTag: authTag.toString('base64'),
|
|
180
|
+
keyVersion: ENCRYPTION_KEY_VERSION
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function decryptPassword(payload) {
|
|
184
|
+
if (!payload || payload.keyVersion !== ENCRYPTION_KEY_VERSION) {
|
|
185
|
+
throw new Error('Unsupported customer portal password encryption version.');
|
|
186
|
+
}
|
|
187
|
+
var key = resolveEncryptionKey();
|
|
188
|
+
var decipher = crypto.createDecipheriv(ALGORITHM, key, Buffer.from(payload.iv, 'base64'));
|
|
189
|
+
decipher.setAuthTag(Buffer.from(payload.authTag, 'base64'));
|
|
190
|
+
var decrypted = Buffer.concat([
|
|
191
|
+
decipher.update(Buffer.from(payload.cipherText, 'base64')),
|
|
192
|
+
decipher.final()
|
|
193
|
+
]);
|
|
194
|
+
return decrypted.toString('utf8');
|
|
195
|
+
}
|
|
196
|
+
function resolveEncryptionKey() {
|
|
197
|
+
var config = resolveio_server_app_1.ResolveIOServer.getServerConfig ? resolveio_server_app_1.ResolveIOServer.getServerConfig() : {};
|
|
198
|
+
var secret = String((config && config['CUSTOMER_PORTAL_PASSWORD_SECRET'])
|
|
199
|
+
|| process.env.CUSTOMER_PORTAL_PASSWORD_SECRET
|
|
200
|
+
|| (config && config['JWT_SECRET'])
|
|
201
|
+
|| process.env.JWT_SECRET
|
|
202
|
+
|| '').trim();
|
|
203
|
+
if (!secret) {
|
|
204
|
+
throw new Error('Missing CUSTOMER_PORTAL_PASSWORD_SECRET (or JWT_SECRET) for customer portal password encryption.');
|
|
205
|
+
}
|
|
206
|
+
return crypto.createHash('sha256').update(secret, 'utf8').digest();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
//# sourceMappingURL=customer-portal-password.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/customer-portal-password.ts"],"names":[],"mappings":"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","file":"customer-portal-password.js","sourcesContent":["import { CustomerPortalPasswords } from '../collections/customer-portal-password.collection';\nimport { UserModel } from '../models/user.model';\nimport { ResolveIOServer } from '../resolveio-server-app';\nconst crypto = require('crypto');\n\nconst ALGORITHM = 'aes-256-gcm';\nconst ENCRYPTION_KEY_VERSION = 1;\nconst IV_LENGTH_BYTES = 12;\n\ninterface PasswordCipherPayload {\n\tcipherText: string;\n\tiv: string;\n\tauthTag: string;\n\tkeyVersion: number;\n}\n\ninterface PasswordRecordMeta {\n\tupdatedByUserId?: string;\n\tupdatedByUser?: string;\n}\n\nexport function isCustomerPortalUser(user: UserModel | any): boolean {\n\tif (!user || typeof user !== 'object') {\n\t\treturn false;\n\t}\n\n\tconst other = user.other || {};\n\tif (other.id_customer) {\n\t\treturn true;\n\t}\n\n\tif (Array.isArray(other.customers) && other.customers.length > 0) {\n\t\treturn true;\n\t}\n\n\tconst groups = Array.isArray(user?.roles?.groups) ? user.roles.groups : [];\n\tif (groups.some(group => {\n\t\tif (!group || typeof group.name !== 'string') {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst normalized = group.name.trim().toLowerCase();\n\t\treturn normalized === 'customer portal' || normalized === 'customer-portal';\n\t})) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nexport async function saveCustomerPortalPassword(user: UserModel | any, password: string, meta?: PasswordRecordMeta): Promise<void> {\n\tif (!user?._id) {\n\t\treturn;\n\t}\n\n\tif (!CustomerPortalPasswords) {\n\t\treturn;\n\t}\n\n\tif (!isCustomerPortalUser(user)) {\n\t\tawait clearCustomerPortalPassword(user._id);\n\t\treturn;\n\t}\n\n\tif (!password || typeof password !== 'string') {\n\t\tawait clearCustomerPortalPassword(user._id);\n\t\treturn;\n\t}\n\n\tconst payload = encryptPassword(password);\n\tconst setData: any = {\n\t\tid_user: user._id,\n\t\tcipher_text: payload.cipherText,\n\t\tiv: payload.iv,\n\t\tauth_tag: payload.authTag,\n\t\tkey_version: payload.keyVersion,\n\t\tlast_set_at: new Date()\n\t};\n\n\tif (meta?.updatedByUserId) {\n\t\tsetData.updated_by_user_id = meta.updatedByUserId;\n\t}\n\n\tif (meta?.updatedByUser) {\n\t\tsetData.updated_by_user = meta.updatedByUser;\n\t}\n\n\tawait CustomerPortalPasswords.updateOne(\n\t\t{id_user: user._id},\n\t\t{\n\t\t\t$set: setData\n\t\t},\n\t\t{upsert: true}\n\t);\n}\n\nexport async function clearCustomerPortalPassword(userId: string): Promise<void> {\n\tif (!userId || !CustomerPortalPasswords) {\n\t\treturn;\n\t}\n\n\tawait CustomerPortalPasswords.deleteOne({id_user: userId});\n}\n\nexport async function getDecryptedCustomerPortalPassword(userId: string): Promise<{password: string; lastSetAt?: Date}> {\n\tif (!userId) {\n\t\tthrow new Error('Customer portal user id is required.');\n\t}\n\n\tif (!CustomerPortalPasswords) {\n\t\tthrow new Error('Customer portal password store is not available.');\n\t}\n\n\tconst record = await CustomerPortalPasswords.findOne({id_user: userId});\n\tif (!record) {\n\t\tthrow new Error('No stored customer portal password is available for this user.');\n\t}\n\n\tconst password = decryptPassword({\n\t\tcipherText: record.cipher_text,\n\t\tiv: record.iv,\n\t\tauthTag: record.auth_tag,\n\t\tkeyVersion: record.key_version\n\t});\n\n\treturn {\n\t\tpassword,\n\t\tlastSetAt: record.last_set_at\n\t};\n}\n\nfunction encryptPassword(plainText: string): PasswordCipherPayload {\n\tconst key = resolveEncryptionKey();\n\tconst ivBuffer = crypto.randomBytes(IV_LENGTH_BYTES);\n\tconst cipher = crypto.createCipheriv(ALGORITHM, key, ivBuffer);\n\tconst encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);\n\tconst authTag = cipher.getAuthTag();\n\n\treturn {\n\t\tcipherText: encrypted.toString('base64'),\n\t\tiv: ivBuffer.toString('base64'),\n\t\tauthTag: authTag.toString('base64'),\n\t\tkeyVersion: ENCRYPTION_KEY_VERSION\n\t};\n}\n\nfunction decryptPassword(payload: PasswordCipherPayload): string {\n\tif (!payload || payload.keyVersion !== ENCRYPTION_KEY_VERSION) {\n\t\tthrow new Error('Unsupported customer portal password encryption version.');\n\t}\n\n\tconst key = resolveEncryptionKey();\n\tconst decipher = crypto.createDecipheriv(\n\t\tALGORITHM,\n\t\tkey,\n\t\tBuffer.from(payload.iv, 'base64')\n\t);\n\tdecipher.setAuthTag(Buffer.from(payload.authTag, 'base64'));\n\n\tconst decrypted = Buffer.concat([\n\t\tdecipher.update(Buffer.from(payload.cipherText, 'base64')),\n\t\tdecipher.final()\n\t]);\n\n\treturn decrypted.toString('utf8');\n}\n\nfunction resolveEncryptionKey(): Buffer {\n\tconst config = ResolveIOServer.getServerConfig ? ResolveIOServer.getServerConfig() : {};\n\tconst secret = String(\n\t\t(config && config['CUSTOMER_PORTAL_PASSWORD_SECRET'])\n\t\t|| process.env.CUSTOMER_PORTAL_PASSWORD_SECRET\n\t\t|| (config && config['JWT_SECRET'])\n\t\t|| process.env.JWT_SECRET\n\t\t|| ''\n\t).trim();\n\n\tif (!secret) {\n\t\tthrow new Error('Missing CUSTOMER_PORTAL_PASSWORD_SECRET (or JWT_SECRET) for customer portal password encryption.');\n\t}\n\n\treturn crypto.createHash('sha256').update(secret, 'utf8').digest();\n}\n"]}
|