orbitx-core-models 11.179.0 → 11.181.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers/chatAttachments.d.ts +4 -3
- package/dist/helpers/chatAttachments.d.ts.map +1 -1
- package/dist/helpers/chatAttachments.js +7 -7
- package/dist/helpers/invoiceDocument.js +1 -1
- package/dist/helpers/ownActivity.js +4 -4
- package/dist/helpers/ownTickets.d.ts +3 -1
- package/dist/helpers/ownTickets.d.ts.map +1 -1
- package/dist/helpers/ownTickets.js +17 -5
- package/dist/helpers/privateFiles.d.ts +14 -0
- package/dist/helpers/privateFiles.d.ts.map +1 -0
- package/dist/helpers/privateFiles.js +45 -0
- package/dist/helpers/s3Storage.d.ts +24 -2
- package/dist/helpers/s3Storage.d.ts.map +1 -1
- package/dist/helpers/s3Storage.js +73 -5
- package/dist/helpers/sessions.d.ts +7 -0
- package/dist/helpers/sessions.d.ts.map +1 -1
- package/dist/helpers/sessions.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/interfaces/company.interface.d.ts +2 -0
- package/dist/interfaces/company.interface.d.ts.map +1 -1
- package/dist/interfaces/tierConfig.interface.d.ts +1 -1
- package/dist/interfaces/tierConfig.interface.d.ts.map +1 -1
- package/dist/models/company.model.d.ts.map +1 -1
- package/dist/models/company.model.js +3 -0
- package/dist/models/invoice.model.js +1 -1
- package/dist/models/monthlyTierSnapshot.model.js +1 -1
- package/dist/models/tierConfig.model.js +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SignFile } from "./privateFiles";
|
|
1
2
|
/**
|
|
2
3
|
* What a chat carries besides text: the files the visitor shared, and the delivery status of every SMS an agent
|
|
3
4
|
* sent. Used by the Employee, Ops and Client backends, so all three dashboards show the same thing.
|
|
@@ -22,11 +23,11 @@ export interface SmsStatusRow {
|
|
|
22
23
|
errorMessage: string | null;
|
|
23
24
|
preview: string;
|
|
24
25
|
}
|
|
25
|
-
/** Files the visitor shared in the chat, oldest first. */
|
|
26
|
-
export declare function getVisitorDocuments(chatId: unknown): Promise<VisitorDocument[]>;
|
|
26
|
+
/** Files the visitor shared in the chat, oldest first. With `signFile`, each link is a signed (private) link. */
|
|
27
|
+
export declare function getVisitorDocuments(chatId: unknown, signFile?: SignFile, seconds?: number): Promise<VisitorDocument[]>;
|
|
27
28
|
/** Every SMS an agent sent in the chat, oldest first, each with its own running number. */
|
|
28
29
|
export declare function getSmsStatus(chatId: unknown): Promise<SmsStatusRow[]>;
|
|
29
|
-
export declare function getChatAttachments(chatId: unknown): Promise<{
|
|
30
|
+
export declare function getChatAttachments(chatId: unknown, signFile?: SignFile): Promise<{
|
|
30
31
|
documents: VisitorDocument[];
|
|
31
32
|
sms: SmsStatusRow[];
|
|
32
33
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatAttachments.d.ts","sourceRoot":"","sources":["../../src/helpers/chatAttachments.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chatAttachments.d.ts","sourceRoot":"","sources":["../../src/helpers/chatAttachments.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;GAGG;AAGH,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,KAAG,MAQ7C,CAAC;AAWF,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,MAAM,EAAE,IAAI,CAAC;IACb,eAAe,EAAE,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,iHAAiH;AACjH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAoB5H;AAED,2FAA2F;AAC3F,wBAAsB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAoB3E;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,eAAe,EAAE,CAAC;IAAC,GAAG,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC,CAG7I"}
|
|
@@ -35,8 +35,8 @@ const kindOf = (mediaType, url) => {
|
|
|
35
35
|
return "audio";
|
|
36
36
|
return "file";
|
|
37
37
|
};
|
|
38
|
-
/** Files the visitor shared in the chat, oldest first. */
|
|
39
|
-
async function getVisitorDocuments(chatId) {
|
|
38
|
+
/** Files the visitor shared in the chat, oldest first. With `signFile`, each link is a signed (private) link. */
|
|
39
|
+
async function getVisitorDocuments(chatId, signFile, seconds) {
|
|
40
40
|
const rows = await message_model_1.Message.find({
|
|
41
41
|
chatId,
|
|
42
42
|
isDeleted: { $ne: true },
|
|
@@ -46,13 +46,13 @@ async function getVisitorDocuments(chatId) {
|
|
|
46
46
|
.sort({ createdAt: 1 })
|
|
47
47
|
.select("mediaUrl mediaType createdAt")
|
|
48
48
|
.lean();
|
|
49
|
-
return rows.map((m) => ({
|
|
49
|
+
return Promise.all(rows.map(async (m) => ({
|
|
50
50
|
id: String(m._id),
|
|
51
|
-
url: m.mediaUrl,
|
|
51
|
+
url: (signFile ? await signFile(m.mediaUrl, seconds) : m.mediaUrl) || m.mediaUrl,
|
|
52
52
|
name: (0, exports.fileNameFromUrl)(m.mediaUrl),
|
|
53
53
|
kind: kindOf(m.mediaType, m.mediaUrl),
|
|
54
54
|
sharedAt: m.createdAt,
|
|
55
|
-
}));
|
|
55
|
+
})));
|
|
56
56
|
}
|
|
57
57
|
/** Every SMS an agent sent in the chat, oldest first, each with its own running number. */
|
|
58
58
|
async function getSmsStatus(chatId) {
|
|
@@ -75,7 +75,7 @@ async function getSmsStatus(chatId) {
|
|
|
75
75
|
preview: String(m.content || "").replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim().slice(0, 120),
|
|
76
76
|
}));
|
|
77
77
|
}
|
|
78
|
-
async function getChatAttachments(chatId) {
|
|
79
|
-
const [documents, sms] = await Promise.all([getVisitorDocuments(chatId), getSmsStatus(chatId)]);
|
|
78
|
+
async function getChatAttachments(chatId, signFile) {
|
|
79
|
+
const [documents, sms] = await Promise.all([getVisitorDocuments(chatId, signFile), getSmsStatus(chatId)]);
|
|
80
80
|
return { documents, sms };
|
|
81
81
|
}
|
|
@@ -35,7 +35,7 @@ function createInvoiceDocuments({ stripe }) {
|
|
|
35
35
|
const CompanyModel = company_model_1.Company;
|
|
36
36
|
const CounterModel = counter_model_1.Counter;
|
|
37
37
|
const LeadLedgerModel = leadLedger_model_1.LeadLedger;
|
|
38
|
-
/** "INV-2026-0001": sequential across
|
|
38
|
+
/** "INV-2026-0001": sequential across ORBITXPRO, starting again each year. */
|
|
39
39
|
async function nextInvoiceNumber(at = new Date()) {
|
|
40
40
|
const year = at.getFullYear();
|
|
41
41
|
const counter = await CounterModel.findByIdAndUpdate(`invoiceNumber_${year}`, { $inc: { seq: 1 } }, { new: true, upsert: true });
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.createOwnActivityController = createOwnActivityController;
|
|
7
7
|
/**
|
|
8
|
-
* A portal's own Activity log: everything done on its account, by its own users and by
|
|
8
|
+
* A portal's own Activity log: everything done on its account, by its own users and by ORBITXPRO staff (HIPAA: an
|
|
9
9
|
* account must be able to see everyone who touched its data). Shown only after Ops turns on the account's access
|
|
10
10
|
* (activityLogAccess). Shared by the Client and Partner backends:
|
|
11
11
|
* createOwnActivityController({ kind: "client" }) // Company accounts, logs filed under `company`
|
|
@@ -39,7 +39,7 @@ function createOwnActivityController({ kind }) {
|
|
|
39
39
|
const listActivity = (0, _http_1.catchAsync)(async (req, res, next) => {
|
|
40
40
|
const account = await Account.findById(accountIdOf(req)).select("activityLogAccess").lean();
|
|
41
41
|
if (!(account === null || account === void 0 ? void 0 : account.activityLogAccess)) {
|
|
42
|
-
return next(new errors_1.AppError("Your Activity log isn't turned on. Please ask
|
|
42
|
+
return next(new errors_1.AppError("Your Activity log isn't turned on. Please ask ORBITXPRO support to turn it on.", _http_1.HTTP.FORBIDDEN));
|
|
43
43
|
}
|
|
44
44
|
const q = req.query;
|
|
45
45
|
const page = Math.max(1, Number(q.page) || 1);
|
|
@@ -78,12 +78,12 @@ function createOwnActivityController({ kind }) {
|
|
|
78
78
|
.lean(),
|
|
79
79
|
ActivityLogModel.countDocuments(filter),
|
|
80
80
|
]);
|
|
81
|
-
//
|
|
81
|
+
// ORBITXPRO staff show by name and team; their work email and network address stay internal.
|
|
82
82
|
const items = rows.map((r) => {
|
|
83
83
|
var _a, _b, _c;
|
|
84
84
|
return ((_a = r.actor) === null || _a === void 0 ? void 0 : _a.kind) === kind
|
|
85
85
|
? r
|
|
86
|
-
: { ...r, actor: { kind: (_b = r.actor) === null || _b === void 0 ? void 0 : _b.kind, name: ((_c = r.actor) === null || _c === void 0 ? void 0 : _c.name) || "
|
|
86
|
+
: { ...r, actor: { kind: (_b = r.actor) === null || _b === void 0 ? void 0 : _b.kind, name: ((_c = r.actor) === null || _c === void 0 ? void 0 : _c.name) || "ORBITXPRO", team: "ORBITXPRO" }, ip: undefined };
|
|
87
87
|
});
|
|
88
88
|
res.status(_http_1.HTTP.OK).json({
|
|
89
89
|
success: true,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { type SignFile } from "./privateFiles";
|
|
2
|
+
export declare function createOwnTicketsController({ ownerType, categoryOptions, fallbackAuthorName, uploadAttachments, raiseDispute, signFile }: {
|
|
2
3
|
ownerType: "Company" | "Partner";
|
|
3
4
|
categoryOptions: any[];
|
|
4
5
|
fallbackAuthorName: string;
|
|
5
6
|
uploadAttachments: (files: any[], ownerId: any) => Promise<any[]>;
|
|
7
|
+
signFile?: SignFile;
|
|
6
8
|
/** Client only: opens the financial dispute behind a lead-dispute ticket. */
|
|
7
9
|
raiseDispute?: (input: {
|
|
8
10
|
leadId: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ownTickets.d.ts","sourceRoot":"","sources":["../../src/helpers/ownTickets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ownTickets.d.ts","sourceRoot":"","sources":["../../src/helpers/ownTickets.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAMhE,wBAAgB,0BAA0B,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE;IACxI,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;IACjC,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAClE,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACvH;;;;;;EAiKA"}
|
|
@@ -12,6 +12,8 @@ exports.createOwnTicketsController = createOwnTicketsController;
|
|
|
12
12
|
* createOwnTicketsController({ ownerType: "Partner", categoryOptions: PARTNER_TICKET_CATEGORY_OPTIONS,
|
|
13
13
|
* fallbackAuthorName: "Partner", uploadAttachments })
|
|
14
14
|
* uploadAttachments(files, ownerId) stores the request's files and resolves the ticket attachment list.
|
|
15
|
+
* signFile(url) turns a stored attachment URL into a signed link (attachments are private files); without it the
|
|
16
|
+
* stored URLs are sent as they are.
|
|
15
17
|
*/
|
|
16
18
|
const mongoose_1 = __importDefault(require("mongoose"));
|
|
17
19
|
const ticket_model_1 = require("../models/ticket.model");
|
|
@@ -22,10 +24,11 @@ const ticketRouting_1 = require("../routing/ticketRouting");
|
|
|
22
24
|
const ticketSanitize_1 = require("../utils/ticketSanitize");
|
|
23
25
|
const errors_1 = require("./errors");
|
|
24
26
|
const _http_1 = require("./_http");
|
|
27
|
+
const privateFiles_1 = require("./privateFiles");
|
|
25
28
|
// Categories where a client disputes one lead/chat: the only ones with a real LeadDispute behind them.
|
|
26
29
|
// "chat-dispute" is a legacy value (no longer offered) kept so an old ticket behaves as it always did.
|
|
27
30
|
const LEAD_DISPUTE_CATEGORIES = ["chat-dispute", "dispute-billable-lead"];
|
|
28
|
-
function createOwnTicketsController({ ownerType, categoryOptions, fallbackAuthorName, uploadAttachments, raiseDispute }) {
|
|
31
|
+
function createOwnTicketsController({ ownerType, categoryOptions, fallbackAuthorName, uploadAttachments, raiseDispute, signFile }) {
|
|
29
32
|
const TicketModel = ticket_model_1.Ticket;
|
|
30
33
|
const UpdateModel = update_model_1.Update;
|
|
31
34
|
const OverrideModel = ticketCategoryOverride_model_1.TicketSubCategoryOverride;
|
|
@@ -127,7 +130,11 @@ function createOwnTicketsController({ ownerType, categoryOptions, fallbackAuthor
|
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
132
|
await routeNewTicket(ticket);
|
|
130
|
-
res.status(_http_1.HTTP.CREATED).json({
|
|
133
|
+
res.status(_http_1.HTTP.CREATED).json({
|
|
134
|
+
success: true,
|
|
135
|
+
message: "Ticket submitted successfully",
|
|
136
|
+
data: { ticket: await (0, privateFiles_1.signTicketFiles)(ticket, signFile), disputeWarning },
|
|
137
|
+
});
|
|
131
138
|
});
|
|
132
139
|
const withPeople = (query) => query.populate("requestedBy", "name email").populate("resolvedBy", "name email");
|
|
133
140
|
const getMyTickets = (0, _http_1.catchAsync)(async (req, res) => {
|
|
@@ -139,13 +146,14 @@ function createOwnTicketsController({ ownerType, categoryOptions, fallbackAuthor
|
|
|
139
146
|
queryObj.category = category;
|
|
140
147
|
const tickets = await withPeople(TicketModel.find(queryObj)).sort({ createdAt: -1 }).lean();
|
|
141
148
|
tickets.forEach(ticketSanitize_1.sanitizeTicketForRequester);
|
|
142
|
-
|
|
149
|
+
const signed = await Promise.all(tickets.map((t) => (0, privateFiles_1.signTicketFiles)(t, signFile)));
|
|
150
|
+
res.status(_http_1.HTTP.OK).json({ success: true, results: signed.length, data: { tickets: signed } });
|
|
143
151
|
});
|
|
144
152
|
const getMyTicketById = (0, _http_1.catchAsync)(async (req, res, next) => {
|
|
145
153
|
const ticket = await withPeople(TicketModel.findOne({ _id: req.params.id, ownerType, ownerId: req.user.owner })).lean();
|
|
146
154
|
if (!ticket)
|
|
147
155
|
return next(new errors_1.AppError("Ticket not found", _http_1.HTTP.NOT_FOUND));
|
|
148
|
-
res.status(_http_1.HTTP.OK).json({ success: true, data: { ticket: (0, ticketSanitize_1.sanitizeTicketForRequester)(ticket) } });
|
|
156
|
+
res.status(_http_1.HTTP.OK).json({ success: true, data: { ticket: await (0, privateFiles_1.signTicketFiles)((0, ticketSanitize_1.sanitizeTicketForRequester)(ticket), signFile) } });
|
|
149
157
|
});
|
|
150
158
|
// A reply from the requester: always visible to them (they can never post an internal note).
|
|
151
159
|
// Body: { body }. File field: attachments (optional, several).
|
|
@@ -170,7 +178,11 @@ function createOwnTicketsController({ ownerType, categoryOptions, fallbackAuthor
|
|
|
170
178
|
};
|
|
171
179
|
await TicketModel.updateOne({ _id: ticket._id }, { $push: { messages: message }, $set: { updatedAt: new Date() } });
|
|
172
180
|
const updated = await withPeople(TicketModel.findById(ticket._id)).lean();
|
|
173
|
-
res.status(_http_1.HTTP.CREATED).json({
|
|
181
|
+
res.status(_http_1.HTTP.CREATED).json({
|
|
182
|
+
success: true,
|
|
183
|
+
message: "Message added",
|
|
184
|
+
data: { ticket: await (0, privateFiles_1.signTicketFiles)((0, ticketSanitize_1.sanitizeTicketForRequester)(updated), signFile) },
|
|
185
|
+
});
|
|
174
186
|
});
|
|
175
187
|
return { getTicketCategories, createTicket, getMyTickets, getMyTicketById, addTicketMessage };
|
|
176
188
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swapping stored file URLs for signed links in what a backend sends out, for the private file folders
|
|
3
|
+
* (PRIVATE_FILE_FOLDERS in s3Storage.ts). Each backend passes its own signer, usually
|
|
4
|
+
* const signFile = (url, seconds) => storage.signUrl(url, seconds);
|
|
5
|
+
* Public files and anything that isn't an S3 link pass through unchanged, so these are safe to call on any data.
|
|
6
|
+
*/
|
|
7
|
+
export type SignFile = (url?: string | null, seconds?: number) => Promise<string | null | undefined>;
|
|
8
|
+
/** A ticket (plain object) with every attachment link signed: the ticket's own and each message's. */
|
|
9
|
+
export declare function signTicketFiles<T = any>(ticket: T, signFile?: SignFile, seconds?: number): Promise<T>;
|
|
10
|
+
/** Chat messages (plain objects) with each mediaUrl signed. */
|
|
11
|
+
export declare function signMessagesMedia<T = any>(messages: T[], signFile?: SignFile, seconds?: number): Promise<T[]>;
|
|
12
|
+
/** A list of rows with an attachment link in `field` (e.g. request attachments), each signed. */
|
|
13
|
+
export declare function signFileList<T = any>(rows: T[] | undefined, signFile?: SignFile, field?: string, seconds?: number): Promise<T[] | undefined>;
|
|
14
|
+
//# sourceMappingURL=privateFiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privateFiles.d.ts","sourceRoot":"","sources":["../../src/helpers/privateFiles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAOrG,sGAAsG;AACtG,wBAAsB,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAe3G;AAED,+DAA+D;AAC/D,wBAAsB,iBAAiB,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CASnH;AAED,iGAAiG;AACjG,wBAAsB,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,SAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,CAGjJ"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Swapping stored file URLs for signed links in what a backend sends out, for the private file folders
|
|
4
|
+
* (PRIVATE_FILE_FOLDERS in s3Storage.ts). Each backend passes its own signer, usually
|
|
5
|
+
* const signFile = (url, seconds) => storage.signUrl(url, seconds);
|
|
6
|
+
* Public files and anything that isn't an S3 link pass through unchanged, so these are safe to call on any data.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.signTicketFiles = signTicketFiles;
|
|
10
|
+
exports.signMessagesMedia = signMessagesMedia;
|
|
11
|
+
exports.signFileList = signFileList;
|
|
12
|
+
const signList = async (list, signFile, field, seconds) => Array.isArray(list)
|
|
13
|
+
? Promise.all(list.map(async (item) => (item && item[field] ? { ...item, [field]: await signFile(item[field], seconds) } : item)))
|
|
14
|
+
: list;
|
|
15
|
+
/** A ticket (plain object) with every attachment link signed: the ticket's own and each message's. */
|
|
16
|
+
async function signTicketFiles(ticket, signFile, seconds) {
|
|
17
|
+
const t = ticket;
|
|
18
|
+
if (!t || !signFile)
|
|
19
|
+
return ticket;
|
|
20
|
+
const plain = typeof t.toObject === "function" ? t.toObject() : t;
|
|
21
|
+
const [attachments, messages] = await Promise.all([
|
|
22
|
+
signList(plain.attachments, signFile, "url", seconds),
|
|
23
|
+
Array.isArray(plain.messages)
|
|
24
|
+
? Promise.all(plain.messages.map(async (m) => m && Array.isArray(m.attachments) ? { ...m, attachments: await signList(m.attachments, signFile, "url", seconds) } : m))
|
|
25
|
+
: plain.messages,
|
|
26
|
+
]);
|
|
27
|
+
return { ...plain, attachments, messages };
|
|
28
|
+
}
|
|
29
|
+
/** Chat messages (plain objects) with each mediaUrl signed. */
|
|
30
|
+
async function signMessagesMedia(messages, signFile, seconds) {
|
|
31
|
+
if (!signFile || !Array.isArray(messages))
|
|
32
|
+
return messages;
|
|
33
|
+
return Promise.all(messages.map(async (m) => {
|
|
34
|
+
if (!(m === null || m === void 0 ? void 0 : m.mediaUrl))
|
|
35
|
+
return m;
|
|
36
|
+
const plain = typeof m.toObject === "function" ? m.toObject() : m;
|
|
37
|
+
return { ...plain, mediaUrl: await signFile(plain.mediaUrl, seconds) };
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
/** A list of rows with an attachment link in `field` (e.g. request attachments), each signed. */
|
|
41
|
+
async function signFileList(rows, signFile, field = "url", seconds) {
|
|
42
|
+
if (!signFile)
|
|
43
|
+
return rows;
|
|
44
|
+
return signList(rows, signFile, field, seconds);
|
|
45
|
+
}
|
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
* The dashboards' S3 file storage: file naming, upload, delete and public links, shared by every backend.
|
|
3
3
|
* A backend passes the AWS SDK it already depends on and its settings, then keeps its own wrapper for the
|
|
4
4
|
* file types it accepts and the messages it shows:
|
|
5
|
-
* const storage = createS3Storage({ sdk: require("@aws-sdk/client-s3"), config: () => env.aws });
|
|
5
|
+
* const storage = createS3Storage({ sdk: require("@aws-sdk/client-s3"), presigner: require("@aws-sdk/s3-request-presigner"), config: () => env.aws });
|
|
6
6
|
* const { key, publicUrl } = await storage.put({ buffer, mimetype, originalname, folder });
|
|
7
|
+
* const link = await storage.signUrl(storedUrlOrKey); // a private file's short-lived link
|
|
8
|
+
*
|
|
9
|
+
* Private files: ticket and request attachments and chat files (folders in PRIVATE_FILE_FOLDERS) are not publicly
|
|
10
|
+
* readable in the bucket. They're stored as before (key + the plain S3 URL), and every response that shows one
|
|
11
|
+
* swaps the stored URL for a signed link that works for a limited time (FILE_LINK_SECONDS).
|
|
7
12
|
*/
|
|
8
13
|
export declare const IMAGE_MIME_TYPES: Set<string>;
|
|
9
14
|
/** Profile photos: no SVG, since these are served as public links. */
|
|
@@ -11,14 +16,28 @@ export declare const PHOTO_MIME_TYPES: Set<string>;
|
|
|
11
16
|
/** What ticket attachments accept: images and documents (PDF, Word, Excel, PowerPoint, text, zip, OpenDocument). */
|
|
12
17
|
export declare const TICKET_ATTACHMENT_MIME_TYPES: Set<string>;
|
|
13
18
|
export declare const sanitizeFileName: (fileName: string) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Folders whose files are private (may hold customers' or visitors' personal details): only reachable through a
|
|
21
|
+
* signed link. Everything else (profile photos, agent aliases, review images) stays public, because website
|
|
22
|
+
* visitors and emails show them directly. The bucket policy must match this list.
|
|
23
|
+
*/
|
|
24
|
+
export declare const PRIVATE_FILE_FOLDERS: string[];
|
|
25
|
+
/** How long a signed link works: long enough for a dashboard page left open all day; emails use the S3 maximum. */
|
|
26
|
+
export declare const FILE_LINK_SECONDS: {
|
|
27
|
+
readonly dashboard: number;
|
|
28
|
+
readonly email: number;
|
|
29
|
+
};
|
|
30
|
+
/** True for a key in one of the private folders. */
|
|
31
|
+
export declare const isPrivateFileKey: (key?: string | null) => boolean;
|
|
14
32
|
export type S3Settings = {
|
|
15
33
|
region?: string;
|
|
16
34
|
bucketName?: string;
|
|
17
35
|
accessKeyId?: string;
|
|
18
36
|
secretAccessKey?: string;
|
|
19
37
|
};
|
|
20
|
-
export declare function createS3Storage({ sdk, config }: {
|
|
38
|
+
export declare function createS3Storage({ sdk, presigner, config }: {
|
|
21
39
|
sdk: any;
|
|
40
|
+
presigner?: any;
|
|
22
41
|
config: () => S3Settings;
|
|
23
42
|
}): {
|
|
24
43
|
put: ({ buffer, mimetype, originalname, folder, fallbackName }: {
|
|
@@ -34,5 +53,8 @@ export declare function createS3Storage({ sdk, config }: {
|
|
|
34
53
|
remove: (key?: string | null) => Promise<void>;
|
|
35
54
|
publicUrlFor: (key: string) => string;
|
|
36
55
|
isConfigured: () => boolean;
|
|
56
|
+
keyFromUrl: (url?: string | null) => string | null;
|
|
57
|
+
signedUrl: (key: string, seconds?: number) => Promise<string>;
|
|
58
|
+
signUrl: (urlOrKey?: string | null, seconds?: number) => Promise<string | null | undefined>;
|
|
37
59
|
};
|
|
38
60
|
//# sourceMappingURL=s3Storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"s3Storage.d.ts","sourceRoot":"","sources":["../../src/helpers/s3Storage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"s3Storage.d.ts","sourceRoot":"","sources":["../../src/helpers/s3Storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,eAAO,MAAM,gBAAgB,aAAmF,CAAC;AAEjH,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,aAAkE,CAAC;AAEhG,oHAAoH;AACpH,eAAO,MAAM,4BAA4B,aAiBvC,CAAC;AAEH,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,KAAG,MAA0D,CAAC;AAE/G;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,UAA+D,CAAC;AAEjG,mHAAmH;AACnH,eAAO,MAAM,iBAAiB;;;CAAgE,CAAC;AAE/F,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,GAAG,IAAI,KAAG,OACiB,CAAC;AAEzE,MAAM,MAAM,UAAU,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElH,wBAAgB,eAAe,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,MAAM,UAAU,CAAA;CAAE;oEA2B3B;QACpF,MAAM,EAAE,GAAG,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,KAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;mBAOnB,MAAM,GAAG,IAAI,KAAG,OAAO,CAAC,IAAI,CAAC;wBAnB9B,MAAM;;uBA4BP,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,IAAI;qBAmBzB,MAAM,YAAW,MAAM,KAAiC,OAAO,CAAC,MAAM,CAAC;yBAWnE,MAAM,GAAG,IAAI,YAAW,MAAM,KAAiC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;EAapI"}
|
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
* The dashboards' S3 file storage: file naming, upload, delete and public links, shared by every backend.
|
|
4
4
|
* A backend passes the AWS SDK it already depends on and its settings, then keeps its own wrapper for the
|
|
5
5
|
* file types it accepts and the messages it shows:
|
|
6
|
-
* const storage = createS3Storage({ sdk: require("@aws-sdk/client-s3"), config: () => env.aws });
|
|
6
|
+
* const storage = createS3Storage({ sdk: require("@aws-sdk/client-s3"), presigner: require("@aws-sdk/s3-request-presigner"), config: () => env.aws });
|
|
7
7
|
* const { key, publicUrl } = await storage.put({ buffer, mimetype, originalname, folder });
|
|
8
|
+
* const link = await storage.signUrl(storedUrlOrKey); // a private file's short-lived link
|
|
9
|
+
*
|
|
10
|
+
* Private files: ticket and request attachments and chat files (folders in PRIVATE_FILE_FOLDERS) are not publicly
|
|
11
|
+
* readable in the bucket. They're stored as before (key + the plain S3 URL), and every response that shows one
|
|
12
|
+
* swaps the stored URL for a signed link that works for a limited time (FILE_LINK_SECONDS).
|
|
8
13
|
*/
|
|
9
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.sanitizeFileName = exports.TICKET_ATTACHMENT_MIME_TYPES = exports.PHOTO_MIME_TYPES = exports.IMAGE_MIME_TYPES = void 0;
|
|
15
|
+
exports.isPrivateFileKey = exports.FILE_LINK_SECONDS = exports.PRIVATE_FILE_FOLDERS = exports.sanitizeFileName = exports.TICKET_ATTACHMENT_MIME_TYPES = exports.PHOTO_MIME_TYPES = exports.IMAGE_MIME_TYPES = void 0;
|
|
11
16
|
exports.createS3Storage = createS3Storage;
|
|
12
17
|
const crypto_1 = require("crypto");
|
|
13
18
|
exports.IMAGE_MIME_TYPES = new Set(["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"]);
|
|
@@ -34,8 +39,19 @@ exports.TICKET_ATTACHMENT_MIME_TYPES = new Set([
|
|
|
34
39
|
]);
|
|
35
40
|
const sanitizeFileName = (fileName) => fileName.trim().replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
36
41
|
exports.sanitizeFileName = sanitizeFileName;
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Folders whose files are private (may hold customers' or visitors' personal details): only reachable through a
|
|
44
|
+
* signed link. Everything else (profile photos, agent aliases, review images) stays public, because website
|
|
45
|
+
* visitors and emails show them directly. The bucket policy must match this list.
|
|
46
|
+
*/
|
|
47
|
+
exports.PRIVATE_FILE_FOLDERS = ["tickets/", "requests/", "partner/tickets/", "chat-media/"];
|
|
48
|
+
/** How long a signed link works: long enough for a dashboard page left open all day; emails use the S3 maximum. */
|
|
49
|
+
exports.FILE_LINK_SECONDS = { dashboard: 12 * 60 * 60, email: 7 * 24 * 60 * 60 };
|
|
50
|
+
/** True for a key in one of the private folders. */
|
|
51
|
+
const isPrivateFileKey = (key) => !!key && exports.PRIVATE_FILE_FOLDERS.some((folder) => key.startsWith(folder));
|
|
52
|
+
exports.isPrivateFileKey = isPrivateFileKey;
|
|
53
|
+
function createS3Storage({ sdk, presigner, config }) {
|
|
54
|
+
const { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand } = sdk;
|
|
39
55
|
let client;
|
|
40
56
|
let clientFor = "";
|
|
41
57
|
const s3 = () => {
|
|
@@ -69,5 +85,57 @@ function createS3Storage({ sdk, config }) {
|
|
|
69
85
|
return;
|
|
70
86
|
await s3().send(new DeleteObjectCommand({ Bucket: config().bucketName, Key: key }));
|
|
71
87
|
}
|
|
72
|
-
|
|
88
|
+
/**
|
|
89
|
+
* The key of a file in this bucket, from its stored S3 URL ("https://<bucket>.s3.<region>.amazonaws.com/<key>",
|
|
90
|
+
* the path-style form, or an already signed link). Null for anything else (another site, a data: URL).
|
|
91
|
+
*/
|
|
92
|
+
function keyFromUrl(url) {
|
|
93
|
+
if (!url || typeof url !== "string")
|
|
94
|
+
return null;
|
|
95
|
+
const { bucketName } = config();
|
|
96
|
+
let parsed;
|
|
97
|
+
try {
|
|
98
|
+
parsed = new URL(url);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const host = parsed.hostname.toLowerCase();
|
|
104
|
+
if (!host.endsWith(".amazonaws.com") || !bucketName)
|
|
105
|
+
return null;
|
|
106
|
+
const path = decodeURIComponent(parsed.pathname.replace(/^\/+/, ""));
|
|
107
|
+
if (host.startsWith(`${bucketName.toLowerCase()}.s3`))
|
|
108
|
+
return path || null;
|
|
109
|
+
// Path-style: s3.<region>.amazonaws.com/<bucket>/<key>
|
|
110
|
+
if (path.startsWith(`${bucketName}/`))
|
|
111
|
+
return path.slice(bucketName.length + 1) || null;
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
/** A link to a stored file that works for `seconds` (S3 allows at most 7 days). */
|
|
115
|
+
async function signedUrl(key, seconds = exports.FILE_LINK_SECONDS.dashboard) {
|
|
116
|
+
if (!(presigner === null || presigner === void 0 ? void 0 : presigner.getSignedUrl) || !GetObjectCommand)
|
|
117
|
+
throw new Error("createS3Storage: pass presigner to sign links");
|
|
118
|
+
const expiresIn = Math.max(60, Math.min(seconds, exports.FILE_LINK_SECONDS.email));
|
|
119
|
+
return presigner.getSignedUrl(s3(), new GetObjectCommand({ Bucket: config().bucketName, Key: key }), { expiresIn });
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* What a response should show for a stored file: a signed link when it's a private file of this bucket, else the
|
|
123
|
+
* stored value unchanged (public files, other sites, empty). Never throws: if signing fails it returns the stored
|
|
124
|
+
* value (the file just won't open once the bucket is private, instead of the whole page failing).
|
|
125
|
+
*/
|
|
126
|
+
async function signUrl(urlOrKey, seconds = exports.FILE_LINK_SECONDS.dashboard) {
|
|
127
|
+
if (!urlOrKey)
|
|
128
|
+
return urlOrKey;
|
|
129
|
+
const key = /^https?:\/\//i.test(urlOrKey) ? keyFromUrl(urlOrKey) : urlOrKey;
|
|
130
|
+
if (!key || !(0, exports.isPrivateFileKey)(key) || !isConfigured())
|
|
131
|
+
return urlOrKey;
|
|
132
|
+
try {
|
|
133
|
+
return await signedUrl(key, seconds);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
console.error("[s3Storage] could not sign a file link:", err === null || err === void 0 ? void 0 : err.message);
|
|
137
|
+
return urlOrKey;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return { put, remove, publicUrlFor, isConfigured, keyFromUrl, signedUrl, signUrl };
|
|
73
141
|
}
|
|
@@ -13,6 +13,13 @@ export type LoginDevice = {
|
|
|
13
13
|
deviceModel?: string;
|
|
14
14
|
platformVersion?: string;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* True when this sign-in comes from a browser the account has never signed in from before, so the person gets a
|
|
18
|
+
* "new sign-in" email. Call it BEFORE createLoginSession (which records the browser). The very first sign-in of an
|
|
19
|
+
* account isn't "new" (there's nothing to compare with), and without a browser id there's nothing to go on.
|
|
20
|
+
* Sessions are never deleted (revoked and expired ones stay), so this sees every browser ever used.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isNewSignInDevice(userId: any, fingerprintId?: string | null): Promise<boolean>;
|
|
16
23
|
/**
|
|
17
24
|
* Stores a new 30-day session for the user and returns its id. Pass the request so the session gets the visitor's
|
|
18
25
|
* real IP address and location (read from the Cloudflare / nginx headers) and the real user agent.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/helpers/sessions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/helpers/sessions.ts"],"names":[],"mappings":"AAiBA,wHAAwH;AACxH,wBAAgB,mBAAmB,IAAI;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAS3E;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,+GAA+G;IAC/G,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAYF;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAQpG;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,GAAG,CAAA;CAAE,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB5G;AAKD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,GAAE,GAAa,GAAG,IAAI,CAYzF;AAKD,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,6GAA6G;IAC7G,UAAU,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB,CAAC;AAEF;gHACgH;AAChH,wBAAgB,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CA4BvF;AAED,mHAAmH;AACnH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAM/H;AAED,gHAAgH;AAChH,wBAAsB,mBAAmB,CAAC,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;;UAQrG;AAED;0GAC0G;AAC1G,wBAAgB,qBAAqB;;;;EA4BpC"}
|
package/dist/helpers/sessions.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateBackupCodes = generateBackupCodes;
|
|
4
|
+
exports.isNewSignInDevice = isNewSignInDevice;
|
|
4
5
|
exports.createLoginSession = createLoginSession;
|
|
5
6
|
exports.touchSession = touchSession;
|
|
6
7
|
exports.sessionView = sessionView;
|
|
@@ -12,6 +13,7 @@ exports.createSessionHandlers = createSessionHandlers;
|
|
|
12
13
|
* login and 2FA flow (they find the account differently); these are the identical pieces:
|
|
13
14
|
* generateBackupCodes() 8 single-use codes, plain for the user and SHA-256 for the database
|
|
14
15
|
* createLoginSession(user, device, req) stores a 30-day session and returns its id (the JWT carries it)
|
|
16
|
+
* isNewSignInDevice(userId, fingerprintId) a sign-in from a browser this account has never used (for the alert email)
|
|
15
17
|
* touchSession(sessionId) marks a session as just used (the Sessions screen's Active / Idle)
|
|
16
18
|
* sessionView(session, currentSessionId) one session as the Sessions screens show it (Ops uses it too)
|
|
17
19
|
* createSessionHandlers() GET my sessions / rename a device / revoke one of my sessions
|
|
@@ -43,6 +45,22 @@ async function savedDeviceName(SessionModel, userId, fingerprintId) {
|
|
|
43
45
|
.lean();
|
|
44
46
|
return (last === null || last === void 0 ? void 0 : last.customName) || undefined;
|
|
45
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* True when this sign-in comes from a browser the account has never signed in from before, so the person gets a
|
|
50
|
+
* "new sign-in" email. Call it BEFORE createLoginSession (which records the browser). The very first sign-in of an
|
|
51
|
+
* account isn't "new" (there's nothing to compare with), and without a browser id there's nothing to go on.
|
|
52
|
+
* Sessions are never deleted (revoked and expired ones stay), so this sees every browser ever used.
|
|
53
|
+
*/
|
|
54
|
+
async function isNewSignInDevice(userId, fingerprintId) {
|
|
55
|
+
if (!userId || !fingerprintId)
|
|
56
|
+
return false;
|
|
57
|
+
const SessionModel = session_model_1.Session;
|
|
58
|
+
const [seenHere, anyBefore] = await Promise.all([
|
|
59
|
+
SessionModel.exists({ userId, fingerprintId }),
|
|
60
|
+
SessionModel.exists({ userId }),
|
|
61
|
+
]);
|
|
62
|
+
return !seenHere && !!anyBefore;
|
|
63
|
+
}
|
|
46
64
|
/**
|
|
47
65
|
* Stores a new 30-day session for the user and returns its id. Pass the request so the session gets the visitor's
|
|
48
66
|
* real IP address and location (read from the Cloudflare / nginx headers) and the real user agent.
|
package/dist/index.d.ts
CHANGED
|
@@ -112,6 +112,7 @@ export * from "./helpers/addonState";
|
|
|
112
112
|
export * from "./helpers/analyticsBuckets";
|
|
113
113
|
export * from "./helpers/contactDecrypt";
|
|
114
114
|
export * from "./helpers/s3Storage";
|
|
115
|
+
export * from "./helpers/privateFiles";
|
|
115
116
|
export * from "./helpers/emailTemplates";
|
|
116
117
|
export * from "./helpers/avatars";
|
|
117
118
|
export * from "./helpers/myUpdates";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -182,6 +182,7 @@ __exportStar(require("./helpers/addonState"), exports);
|
|
|
182
182
|
__exportStar(require("./helpers/analyticsBuckets"), exports);
|
|
183
183
|
__exportStar(require("./helpers/contactDecrypt"), exports);
|
|
184
184
|
__exportStar(require("./helpers/s3Storage"), exports);
|
|
185
|
+
__exportStar(require("./helpers/privateFiles"), exports);
|
|
185
186
|
__exportStar(require("./helpers/emailTemplates"), exports);
|
|
186
187
|
__exportStar(require("./helpers/avatars"), exports);
|
|
187
188
|
__exportStar(require("./helpers/myUpdates"), exports);
|
|
@@ -88,6 +88,8 @@ export interface ICompany extends mongoose.Document {
|
|
|
88
88
|
clientInstructionEnabled?: boolean;
|
|
89
89
|
/** Ops granted this client access to its own Activity log. */
|
|
90
90
|
activityLogAccess?: boolean;
|
|
91
|
+
/** Month ("YYYY-MM") of the last monthly summary email sent to the main contact. */
|
|
92
|
+
monthlySummarySentFor?: string;
|
|
91
93
|
/** Ordered script folders (Vertical ids) Ops chose for this company. */
|
|
92
94
|
scriptVerticals?: Types.ObjectId[];
|
|
93
95
|
scriptBot?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"company.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/company.interface.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"company.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/company.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tierConfig.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/tierConfig.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,MAAM,QAAQ,GAAG,
|
|
1
|
+
{"version":3,"file":"tierConfig.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/tierConfig.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"company.model.d.ts","sourceRoot":"","sources":["../../src/models/company.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAA2B,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"company.model.d.ts","sourceRoot":"","sources":["../../src/models/company.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAA2B,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AA+Q3D,eAAO,MAAM,OAAO;;;;OAAqD,CAAC;AAC1E,eAAe,OAAO,CAAC"}
|
|
@@ -42,6 +42,9 @@ const companySchema = new mongoose_1.Schema({
|
|
|
42
42
|
clientInstructionEnabled: { type: Boolean, default: false },
|
|
43
43
|
// Ops-controlled: the client can see its own company's Activity log (given on request).
|
|
44
44
|
activityLogAccess: { type: Boolean, default: false },
|
|
45
|
+
// The month ("2026-09") whose summary email was last sent to the company's main contact; set before
|
|
46
|
+
// sending (an atomic claim), so a restart or a second run never sends the same month twice.
|
|
47
|
+
monthlySummarySentFor: { type: String },
|
|
45
48
|
// The script folders Ops picked for this company (Account > Script > Insert Vertical), in the
|
|
46
49
|
// order they were arranged. Agents see exactly these, in this order, when the company's chat
|
|
47
50
|
// lands, and so does the lead page's View Script panel.
|
|
@@ -107,7 +107,7 @@ const invoiceSchema = new mongoose_1.Schema({
|
|
|
107
107
|
required: [true, "Total due is required"],
|
|
108
108
|
min: 0,
|
|
109
109
|
},
|
|
110
|
-
// The number printed on the invoice: "INV-2026-0001", sequential across
|
|
110
|
+
// The number printed on the invoice: "INV-2026-0001", sequential across ORBITXPRO per year.
|
|
111
111
|
invoiceNumber: {
|
|
112
112
|
type: String,
|
|
113
113
|
trim: true,
|