orbitx-core-models 11.178.0 → 11.179.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/activity/recorder.d.ts +2 -2
- package/dist/activity/recorder.d.ts.map +1 -1
- package/dist/activity/recorder.js +4 -7
- package/dist/constants/ticketCategories.d.ts +41 -20
- package/dist/constants/ticketCategories.d.ts.map +1 -1
- package/dist/constants/ticketCategories.js +212 -53
- package/dist/helpers/emailTemplates.d.ts.map +1 -1
- package/dist/helpers/emailTemplates.js +4 -5
- package/dist/helpers/ownTickets.d.ts.map +1 -1
- package/dist/helpers/ownTickets.js +13 -6
- package/dist/helpers/requestInfo.d.ts +47 -0
- package/dist/helpers/requestInfo.d.ts.map +1 -0
- package/dist/helpers/requestInfo.js +156 -0
- package/dist/helpers/sessions.d.ts +44 -3
- package/dist/helpers/sessions.d.ts.map +1 -1
- package/dist/helpers/sessions.js +126 -11
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/interfaces/session.interface.d.ts +2 -0
- package/dist/interfaces/session.interface.d.ts.map +1 -1
- package/dist/interfaces/subscription.interface.d.ts +2 -0
- package/dist/interfaces/subscription.interface.d.ts.map +1 -1
- package/dist/interfaces/ticket.interface.d.ts +30 -26
- package/dist/interfaces/ticket.interface.d.ts.map +1 -1
- package/dist/interfaces/ticket.interface.js +28 -4
- package/dist/interfaces/user.interface.d.ts +4 -0
- package/dist/interfaces/user.interface.d.ts.map +1 -1
- package/dist/interfaces/vertical.interface.d.ts +1 -1
- package/dist/interfaces/vertical.interface.d.ts.map +1 -1
- package/dist/models/session.model.d.ts.map +1 -1
- package/dist/models/session.model.js +4 -0
- package/dist/models/subscription.model.d.ts.map +1 -1
- package/dist/models/subscription.model.js +4 -0
- package/dist/models/ticket.model.d.ts.map +1 -1
- package/dist/models/ticket.model.js +24 -38
- package/dist/models/user.model.d.ts.map +1 -1
- package/dist/models/user.model.js +7 -0
- package/dist/models/vertical.model.js +1 -1
- package/dist/routing/ticketRouting.d.ts +11 -1
- package/dist/routing/ticketRouting.d.ts.map +1 -1
- package/dist/routing/ticketRouting.js +82 -33
- package/dist/utils/ticketSanitize.d.ts.map +1 -1
- package/dist/utils/ticketSanitize.js +4 -0
- package/package.json +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who is signing in, as far as the request can tell, for every backend's sign-in sessions and the activity log:
|
|
3
|
+
* clientIp(req) the visitor's real IP address
|
|
4
|
+
* requestLocation(req) "Lahore, Pakistan" from Cloudflare's visitor-location headers
|
|
5
|
+
* describeDevice(userAgent, hints) a readable device ("Windows PC", "iPhone", "Samsung SM-S911B"), browser and OS
|
|
6
|
+
* isPrivateIp(ip) true for proxy / Docker / local addresses, which say nothing about the visitor
|
|
7
|
+
*
|
|
8
|
+
* Requests reach the backends through nginx (and Cloudflare on proxied hosts), so the socket address is the proxy's
|
|
9
|
+
* (inside Docker, the bridge gateway "::ffff:172.18.0.1"), never the visitor's.
|
|
10
|
+
*/
|
|
11
|
+
type Req = any;
|
|
12
|
+
/** "::ffff:1.2.3.4" (an IPv4 address written the IPv6 way) -> "1.2.3.4". */
|
|
13
|
+
export declare function normalizeIp(ip?: string | null): string | undefined;
|
|
14
|
+
/** Loopback, private-network and link-local addresses: what a proxy or Docker hands on, not a visitor's address. */
|
|
15
|
+
export declare function isPrivateIp(ip?: string | null): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The visitor's IP address, in order of trust:
|
|
18
|
+
* CF-Connecting-IP set by Cloudflare on proxied hosts (client.orbitxpro.com)
|
|
19
|
+
* X-Real-IP set by nginx from the connecting address (on a Cloudflare-proxied host this is Cloudflare's)
|
|
20
|
+
* X-Forwarded-For first entry
|
|
21
|
+
* the socket only right when nothing sits in front of the app
|
|
22
|
+
*/
|
|
23
|
+
export declare function clientIp(req: Req): string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Where the request came from, from Cloudflare's visitor-location headers: "Lahore, Pakistan", or just "Pakistan".
|
|
26
|
+
* Only Cloudflare-proxied hosts get these. The country comes with every proxied request; the city and region only
|
|
27
|
+
* when the zone's "Add visitor location headers" Managed Transform is on. Nothing (undefined) otherwise.
|
|
28
|
+
*/
|
|
29
|
+
export declare function requestLocation(req: Req): string | undefined;
|
|
30
|
+
/** What the browser can add beyond the user agent (Chrome's `navigator.userAgentData`): the Android phone model and
|
|
31
|
+
* the real OS version (the only way to tell Windows 11 from Windows 10). */
|
|
32
|
+
export type DeviceHints = {
|
|
33
|
+
model?: string;
|
|
34
|
+
platformVersion?: string;
|
|
35
|
+
};
|
|
36
|
+
export type DeviceDescription = {
|
|
37
|
+
deviceName: string;
|
|
38
|
+
browser: string;
|
|
39
|
+
os: string;
|
|
40
|
+
};
|
|
41
|
+
/** Reads the user agent (plus the browser's hints when sent) into a device name, browser and OS. iPhones only ever
|
|
42
|
+
* say "iPhone" (no model), and laptops never say their brand: the person can name the device themselves. */
|
|
43
|
+
export declare function describeDevice(userAgent?: string | null, hints?: DeviceHints): DeviceDescription;
|
|
44
|
+
/** A name the person gave a device: trimmed, at most 40 characters, "" to clear it. */
|
|
45
|
+
export declare function cleanDeviceName(value: unknown): string;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=requestInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestInfo.d.ts","sourceRoot":"","sources":["../../src/helpers/requestInfo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,KAAK,GAAG,GAAG,GAAG,CAAC;AAOf,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAKlE;AAED,oHAAoH;AACpH,wBAAgB,WAAW,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CASvD;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAKrD;AAiBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAS5D;AAED;6EAC6E;AAC7E,MAAM,MAAM,WAAW,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,MAAM,MAAM,iBAAiB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAyBpF;6GAC6G;AAC7G,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,GAAE,WAAgB,GAAG,iBAAiB,CA8CpG;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Who is signing in, as far as the request can tell, for every backend's sign-in sessions and the activity log:
|
|
4
|
+
* clientIp(req) the visitor's real IP address
|
|
5
|
+
* requestLocation(req) "Lahore, Pakistan" from Cloudflare's visitor-location headers
|
|
6
|
+
* describeDevice(userAgent, hints) a readable device ("Windows PC", "iPhone", "Samsung SM-S911B"), browser and OS
|
|
7
|
+
* isPrivateIp(ip) true for proxy / Docker / local addresses, which say nothing about the visitor
|
|
8
|
+
*
|
|
9
|
+
* Requests reach the backends through nginx (and Cloudflare on proxied hosts), so the socket address is the proxy's
|
|
10
|
+
* (inside Docker, the bridge gateway "::ffff:172.18.0.1"), never the visitor's.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.normalizeIp = normalizeIp;
|
|
14
|
+
exports.isPrivateIp = isPrivateIp;
|
|
15
|
+
exports.clientIp = clientIp;
|
|
16
|
+
exports.requestLocation = requestLocation;
|
|
17
|
+
exports.describeDevice = describeDevice;
|
|
18
|
+
exports.cleanDeviceName = cleanDeviceName;
|
|
19
|
+
const header = (req, name) => {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
const value = (_a = req === null || req === void 0 ? void 0 : req.headers) === null || _a === void 0 ? void 0 : _a[name];
|
|
22
|
+
return String((_b = (Array.isArray(value) ? value[0] : value)) !== null && _b !== void 0 ? _b : "").trim();
|
|
23
|
+
};
|
|
24
|
+
/** "::ffff:1.2.3.4" (an IPv4 address written the IPv6 way) -> "1.2.3.4". */
|
|
25
|
+
function normalizeIp(ip) {
|
|
26
|
+
if (!ip)
|
|
27
|
+
return undefined;
|
|
28
|
+
let value = String(ip).trim();
|
|
29
|
+
if (/^::ffff:\d+\.\d+\.\d+\.\d+$/i.test(value))
|
|
30
|
+
value = value.slice(7);
|
|
31
|
+
return value || undefined;
|
|
32
|
+
}
|
|
33
|
+
/** Loopback, private-network and link-local addresses: what a proxy or Docker hands on, not a visitor's address. */
|
|
34
|
+
function isPrivateIp(ip) {
|
|
35
|
+
const value = normalizeIp(ip);
|
|
36
|
+
if (!value)
|
|
37
|
+
return true;
|
|
38
|
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(value)) {
|
|
39
|
+
const [a, b] = value.split(".").map(Number);
|
|
40
|
+
return a === 10 || a === 127 || (a === 172 && b >= 16 && b <= 31) || (a === 192 && b === 168) || (a === 169 && b === 254);
|
|
41
|
+
}
|
|
42
|
+
const lower = value.toLowerCase();
|
|
43
|
+
return lower === "::1" || lower.startsWith("fc") || lower.startsWith("fd") || lower.startsWith("fe80:");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The visitor's IP address, in order of trust:
|
|
47
|
+
* CF-Connecting-IP set by Cloudflare on proxied hosts (client.orbitxpro.com)
|
|
48
|
+
* X-Real-IP set by nginx from the connecting address (on a Cloudflare-proxied host this is Cloudflare's)
|
|
49
|
+
* X-Forwarded-For first entry
|
|
50
|
+
* the socket only right when nothing sits in front of the app
|
|
51
|
+
*/
|
|
52
|
+
function clientIp(req) {
|
|
53
|
+
var _a;
|
|
54
|
+
const forwarded = header(req, "x-forwarded-for").split(",")[0].trim();
|
|
55
|
+
return normalizeIp(header(req, "cf-connecting-ip") || header(req, "x-real-ip") || forwarded || ((_a = req === null || req === void 0 ? void 0 : req.socket) === null || _a === void 0 ? void 0 : _a.remoteAddress) || (req === null || req === void 0 ? void 0 : req.ip));
|
|
56
|
+
}
|
|
57
|
+
// Cloudflare sends non-English city names as raw UTF-8 bytes, which Node reads as Latin-1.
|
|
58
|
+
function fixEncoding(value) {
|
|
59
|
+
if (!/[\u0080-ÿ]/.test(value))
|
|
60
|
+
return value;
|
|
61
|
+
const decoded = Buffer.from(value, "latin1").toString("utf8");
|
|
62
|
+
return decoded.includes("�") ? value : decoded;
|
|
63
|
+
}
|
|
64
|
+
function countryName(code) {
|
|
65
|
+
try {
|
|
66
|
+
return new Intl.DisplayNames(["en"], { type: "region" }).of(code) || code;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return code;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Where the request came from, from Cloudflare's visitor-location headers: "Lahore, Pakistan", or just "Pakistan".
|
|
74
|
+
* Only Cloudflare-proxied hosts get these. The country comes with every proxied request; the city and region only
|
|
75
|
+
* when the zone's "Add visitor location headers" Managed Transform is on. Nothing (undefined) otherwise.
|
|
76
|
+
*/
|
|
77
|
+
function requestLocation(req) {
|
|
78
|
+
const code = header(req, "cf-ipcountry").toUpperCase();
|
|
79
|
+
// XX = unknown, T1 = Tor.
|
|
80
|
+
const country = /^[A-Z]{2}$/.test(code) && code !== "XX" && code !== "T1" ? countryName(code) : "";
|
|
81
|
+
const city = fixEncoding(header(req, "cf-ipcity"));
|
|
82
|
+
const region = fixEncoding(header(req, "cf-region"));
|
|
83
|
+
const place = city || region;
|
|
84
|
+
const parts = [place, country].filter(Boolean);
|
|
85
|
+
return parts.length ? parts.join(", ").slice(0, 120) : undefined;
|
|
86
|
+
}
|
|
87
|
+
const clean = (value, max = 60) => typeof value === "string" ? value.replace(/[^\w .,()+\-/]/g, "").trim().slice(0, max) : "";
|
|
88
|
+
function describeBrowser(ua) {
|
|
89
|
+
const pick = (name, re) => {
|
|
90
|
+
const m = ua.match(re);
|
|
91
|
+
return m ? `${name} ${m[1]}` : null;
|
|
92
|
+
};
|
|
93
|
+
return (pick("Edge", /\bEdg(?:e|A|iOS)?\/(\d+)/) ||
|
|
94
|
+
pick("Opera", /\b(?:OPR|OPX)\/(\d+)/) ||
|
|
95
|
+
pick("Samsung Internet", /\bSamsungBrowser\/(\d+)/) ||
|
|
96
|
+
pick("Firefox", /\b(?:Firefox|FxiOS)\/(\d+)/) ||
|
|
97
|
+
pick("Chrome", /\bCriOS\/(\d+)/) ||
|
|
98
|
+
(!/Chromium/.test(ua) ? pick("Chrome", /\bChrome\/(\d+)/) : null) ||
|
|
99
|
+
pick("Chromium", /\bChromium\/(\d+)/) ||
|
|
100
|
+
(/Safari\//.test(ua) ? pick("Safari", /\bVersion\/(\d+(?:\.\d+)?)/) || "Safari" : null) ||
|
|
101
|
+
"Unknown browser");
|
|
102
|
+
}
|
|
103
|
+
const WINDOWS_NT = { "6.3": "Windows 8.1", "6.2": "Windows 8", "6.1": "Windows 7" };
|
|
104
|
+
/** Reads the user agent (plus the browser's hints when sent) into a device name, browser and OS. iPhones only ever
|
|
105
|
+
* say "iPhone" (no model), and laptops never say their brand: the person can name the device themselves. */
|
|
106
|
+
function describeDevice(userAgent, hints = {}) {
|
|
107
|
+
var _a, _b;
|
|
108
|
+
const ua = String(userAgent || "");
|
|
109
|
+
const browser = describeBrowser(ua);
|
|
110
|
+
const model = clean(hints.model);
|
|
111
|
+
const platformMajor = parseInt(clean(hints.platformVersion, 20), 10);
|
|
112
|
+
const apple = ua.match(/\b(iPhone|iPad|iPod)\b/);
|
|
113
|
+
if (apple) {
|
|
114
|
+
const version = ua.match(/OS (\d+)[_.](\d+)/);
|
|
115
|
+
const osName = apple[1] === "iPad" ? "iPadOS" : "iOS";
|
|
116
|
+
return { deviceName: apple[1], browser, os: version ? `${osName} ${version[1]}.${version[2]}` : osName };
|
|
117
|
+
}
|
|
118
|
+
const android = ua.match(/Android (\d+(?:\.\d+)?)/);
|
|
119
|
+
if (android || /Android/.test(ua)) {
|
|
120
|
+
// Older user agents name the model ("Android 10; SM-G973F Build/..."); current Chrome sends "K" instead and only
|
|
121
|
+
// tells the model through the hints.
|
|
122
|
+
const uaModel = (_b = (_a = ua.match(/Android [\d.]+; ([^;)]+?)(?: Build\/|\))/)) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.trim();
|
|
123
|
+
const found = (model || (uaModel && uaModel !== "K" ? clean(uaModel) : "")).replace(/^samsung\s+/i, "");
|
|
124
|
+
const deviceName = found
|
|
125
|
+
? /^SM-/i.test(found)
|
|
126
|
+
? `Samsung ${found}`
|
|
127
|
+
: found
|
|
128
|
+
: /Mobile/.test(ua)
|
|
129
|
+
? "Android phone"
|
|
130
|
+
: "Android tablet";
|
|
131
|
+
// Current Chrome freezes the version in the user agent ("Android 10"); the hint has the real one.
|
|
132
|
+
const version = Number.isFinite(platformMajor) && platformMajor > 0 ? String(platformMajor) : android === null || android === void 0 ? void 0 : android[1];
|
|
133
|
+
return { deviceName, browser, os: version ? `Android ${version}` : "Android" };
|
|
134
|
+
}
|
|
135
|
+
const windows = ua.match(/Windows NT (\d+\.\d+)/);
|
|
136
|
+
if (windows) {
|
|
137
|
+
let os = WINDOWS_NT[windows[1]] || "Windows";
|
|
138
|
+
if (windows[1] === "10.0") {
|
|
139
|
+
// Windows 11 reports itself as NT 10.0; only the hint's platform version (13 and up) tells them apart.
|
|
140
|
+
os = Number.isFinite(platformMajor) ? (platformMajor >= 13 ? "Windows 11" : "Windows 10") : "Windows 10/11";
|
|
141
|
+
}
|
|
142
|
+
return { deviceName: "Windows PC", browser, os };
|
|
143
|
+
}
|
|
144
|
+
// Browsers freeze the macOS version in the user agent (10.15.7), so it isn't shown.
|
|
145
|
+
if (/Macintosh|Mac OS X/.test(ua))
|
|
146
|
+
return { deviceName: "Mac", browser, os: "macOS" };
|
|
147
|
+
if (/CrOS/.test(ua))
|
|
148
|
+
return { deviceName: "Chromebook", browser, os: "ChromeOS" };
|
|
149
|
+
if (/Linux/.test(ua))
|
|
150
|
+
return { deviceName: "Linux PC", browser, os: "Linux" };
|
|
151
|
+
return { deviceName: "Unknown device", browser, os: "Unknown OS" };
|
|
152
|
+
}
|
|
153
|
+
/** A name the person gave a device: trimmed, at most 40 characters, "" to clear it. */
|
|
154
|
+
function cleanDeviceName(value) {
|
|
155
|
+
return typeof value === "string" ? value.replace(/\s+/g, " ").trim().slice(0, 40) : "";
|
|
156
|
+
}
|
|
@@ -9,14 +9,55 @@ export type LoginDevice = {
|
|
|
9
9
|
os?: string;
|
|
10
10
|
userAgent?: string;
|
|
11
11
|
ip?: string;
|
|
12
|
+
/** From the browser's hints (Chrome's navigator.userAgentData): the Android phone model and the OS version. */
|
|
13
|
+
deviceModel?: string;
|
|
14
|
+
platformVersion?: string;
|
|
12
15
|
};
|
|
13
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Stores a new 30-day session for the user and returns its id. Pass the request so the session gets the visitor's
|
|
18
|
+
* real IP address and location (read from the Cloudflare / nginx headers) and the real user agent.
|
|
19
|
+
*/
|
|
14
20
|
export declare function createLoginSession(user: {
|
|
15
21
|
_id: any;
|
|
16
|
-
},
|
|
17
|
-
/**
|
|
22
|
+
}, device: LoginDevice, req?: any): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Marks the session as used just now, so the Sessions screen can tell Active from Idle. At most one small write per
|
|
25
|
+
* session every 5 minutes, never awaited and never failing the request. Ops passes its own session model.
|
|
26
|
+
*/
|
|
27
|
+
export declare function touchSession(sessionId?: string | null, SessionModel?: any): void;
|
|
28
|
+
export type SessionView = {
|
|
29
|
+
_id: string;
|
|
30
|
+
sessionId: string;
|
|
31
|
+
/** What to call the device: the person's own name for it, else the detected one ("Windows PC", "iPhone"). */
|
|
32
|
+
deviceName: string;
|
|
33
|
+
/** The detected name, shown under a custom name and used to prefill "Name this device". */
|
|
34
|
+
detectedName: string;
|
|
35
|
+
customName?: string;
|
|
36
|
+
browser?: string;
|
|
37
|
+
os?: string;
|
|
38
|
+
/** Unset when only a proxy's address was recorded (sign-ins before the real-IP fix). */
|
|
39
|
+
ipAddress?: string;
|
|
40
|
+
location?: string;
|
|
41
|
+
isCurrent: boolean;
|
|
42
|
+
status: "active" | "idle";
|
|
43
|
+
lastActiveAt?: Date;
|
|
44
|
+
createdAt?: Date;
|
|
45
|
+
expiresAt?: Date;
|
|
46
|
+
};
|
|
47
|
+
/** One session as the Sessions screens show it. Sessions from before Oct 2026 stored no device name (Client /
|
|
48
|
+
* Partner) or an old "Chrome 129 on Windows 10/11" label (Ops); those are read again from their user agent. */
|
|
49
|
+
export declare function sessionView(session: any, currentSessionId?: string | null): SessionView;
|
|
50
|
+
/** The signed-in user's sessions as the Sessions screen shows them: this device first, then most recently used. */
|
|
51
|
+
export declare function listSessionViews(SessionModel: any, userId: any, currentSessionId?: string | null): Promise<SessionView[]>;
|
|
52
|
+
/** Names one of the user's devices (all of that device's sessions, so later sign-ins keep it); "" clears it. */
|
|
53
|
+
export declare function renameSessionDevice(SessionModel: any, userId: any, id: string, rawName: unknown): Promise<{
|
|
54
|
+
name: string;
|
|
55
|
+
} | null>;
|
|
56
|
+
/** The signed-in user's open sessions, naming a device, and revoking a session. The backend's protect middleware
|
|
57
|
+
* sets req.sessionId (the JWT's session) so "This device" is marked here, not guessed in the browser. */
|
|
18
58
|
export declare function createSessionHandlers(): {
|
|
19
59
|
getSessions: (req: any, res: any, next: any) => void;
|
|
60
|
+
renameSession: (req: any, res: any, next: any) => void;
|
|
20
61
|
revokeSession: (req: any, res: any, next: any) => void;
|
|
21
62
|
};
|
|
22
63
|
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -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":"AAgBA,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;;;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
|
@@ -2,18 +2,26 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateBackupCodes = generateBackupCodes;
|
|
4
4
|
exports.createLoginSession = createLoginSession;
|
|
5
|
+
exports.touchSession = touchSession;
|
|
6
|
+
exports.sessionView = sessionView;
|
|
7
|
+
exports.listSessionViews = listSessionViews;
|
|
8
|
+
exports.renameSessionDevice = renameSessionDevice;
|
|
5
9
|
exports.createSessionHandlers = createSessionHandlers;
|
|
6
10
|
/**
|
|
7
11
|
* Sign-in sessions and 2FA backup codes shared by the Client and Partner backends. Each backend keeps its own
|
|
8
12
|
* login and 2FA flow (they find the account differently); these are the identical pieces:
|
|
9
13
|
* generateBackupCodes() 8 single-use codes, plain for the user and SHA-256 for the database
|
|
10
|
-
* createLoginSession(user, device)
|
|
11
|
-
*
|
|
14
|
+
* createLoginSession(user, device, req) stores a 30-day session and returns its id (the JWT carries it)
|
|
15
|
+
* touchSession(sessionId) marks a session as just used (the Sessions screen's Active / Idle)
|
|
16
|
+
* sessionView(session, currentSessionId) one session as the Sessions screens show it (Ops uses it too)
|
|
17
|
+
* createSessionHandlers() GET my sessions / rename a device / revoke one of my sessions
|
|
12
18
|
*/
|
|
13
19
|
const crypto_1 = require("crypto");
|
|
20
|
+
const mongoose_1 = require("mongoose");
|
|
14
21
|
const session_model_1 = require("../models/session.model");
|
|
15
22
|
const errors_1 = require("./errors");
|
|
16
23
|
const _http_1 = require("./_http");
|
|
24
|
+
const requestInfo_1 = require("./requestInfo");
|
|
17
25
|
/** 8 single-use backup codes, e.g. "A3F9B2C1D4". Stored as SHA-256 hashes so the server never holds the plain codes. */
|
|
18
26
|
function generateBackupCodes() {
|
|
19
27
|
const plain = [];
|
|
@@ -25,31 +33,138 @@ function generateBackupCodes() {
|
|
|
25
33
|
}
|
|
26
34
|
return { plain, hashed };
|
|
27
35
|
}
|
|
28
|
-
/**
|
|
29
|
-
async function
|
|
36
|
+
/** The name the person gave this device on an earlier sign-in (renaming applies to all of a device's sessions). */
|
|
37
|
+
async function savedDeviceName(SessionModel, userId, fingerprintId) {
|
|
38
|
+
if (!fingerprintId)
|
|
39
|
+
return undefined;
|
|
40
|
+
const last = await SessionModel.findOne({ userId, fingerprintId, customName: { $nin: [null, ""] } })
|
|
41
|
+
.sort("-createdAt")
|
|
42
|
+
.select("customName")
|
|
43
|
+
.lean();
|
|
44
|
+
return (last === null || last === void 0 ? void 0 : last.customName) || undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Stores a new 30-day session for the user and returns its id. Pass the request so the session gets the visitor's
|
|
48
|
+
* real IP address and location (read from the Cloudflare / nginx headers) and the real user agent.
|
|
49
|
+
*/
|
|
50
|
+
async function createLoginSession(user, device, req) {
|
|
51
|
+
var _a;
|
|
30
52
|
const sessionId = (0, crypto_1.randomBytes)(32).toString("hex");
|
|
53
|
+
const userAgent = String(((_a = req === null || req === void 0 ? void 0 : req.headers) === null || _a === void 0 ? void 0 : _a["user-agent"]) || device.userAgent || "").slice(0, 500) || undefined;
|
|
54
|
+
const detected = (0, requestInfo_1.describeDevice)(userAgent, { model: device.deviceModel, platformVersion: device.platformVersion });
|
|
31
55
|
await session_model_1.Session.create({
|
|
32
56
|
userId: user._id,
|
|
33
57
|
sessionId,
|
|
34
|
-
fingerprintId,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
58
|
+
fingerprintId: device.fingerprintId,
|
|
59
|
+
deviceName: userAgent ? detected.deviceName : undefined,
|
|
60
|
+
browser: userAgent ? detected.browser : device.browser,
|
|
61
|
+
os: userAgent ? detected.os : device.os,
|
|
62
|
+
ipAddress: req ? (0, requestInfo_1.clientIp)(req) : (0, requestInfo_1.normalizeIp)(device.ip),
|
|
63
|
+
location: req ? (0, requestInfo_1.requestLocation)(req) : undefined,
|
|
38
64
|
userAgent,
|
|
65
|
+
customName: await savedDeviceName(session_model_1.Session, user._id, device.fingerprintId),
|
|
39
66
|
isRevoked: false,
|
|
40
67
|
lastActiveAt: new Date(),
|
|
41
68
|
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
|
|
42
69
|
});
|
|
43
70
|
return sessionId;
|
|
44
71
|
}
|
|
45
|
-
|
|
72
|
+
const TOUCH_EVERY_MS = 5 * 60 * 1000;
|
|
73
|
+
const lastTouched = new Map();
|
|
74
|
+
/**
|
|
75
|
+
* Marks the session as used just now, so the Sessions screen can tell Active from Idle. At most one small write per
|
|
76
|
+
* session every 5 minutes, never awaited and never failing the request. Ops passes its own session model.
|
|
77
|
+
*/
|
|
78
|
+
function touchSession(sessionId, SessionModel = session_model_1.Session) {
|
|
79
|
+
if (!sessionId)
|
|
80
|
+
return;
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
const last = lastTouched.get(sessionId);
|
|
83
|
+
if (last && now - last < TOUCH_EVERY_MS)
|
|
84
|
+
return;
|
|
85
|
+
lastTouched.set(sessionId, now);
|
|
86
|
+
if (lastTouched.size > 10000) {
|
|
87
|
+
for (const [id, at] of lastTouched)
|
|
88
|
+
if (now - at >= TOUCH_EVERY_MS)
|
|
89
|
+
lastTouched.delete(id);
|
|
90
|
+
}
|
|
91
|
+
Promise.resolve(SessionModel.updateOne({ sessionId }, { $set: { lastActiveAt: new Date(now) } })).catch(() => lastTouched.delete(sessionId));
|
|
92
|
+
}
|
|
93
|
+
/** Used within this long = "Active", otherwise "Idle". touchSession writes every 5 minutes, so this leaves room. */
|
|
94
|
+
const ACTIVE_WINDOW_MS = 30 * 60 * 1000;
|
|
95
|
+
/** One session as the Sessions screens show it. Sessions from before Oct 2026 stored no device name (Client /
|
|
96
|
+
* Partner) or an old "Chrome 129 on Windows 10/11" label (Ops); those are read again from their user agent. */
|
|
97
|
+
function sessionView(session, currentSessionId) {
|
|
98
|
+
const s = (session === null || session === void 0 ? void 0 : session.toObject) ? session.toObject() : session;
|
|
99
|
+
const current = Boolean(currentSessionId) && s.sessionId === currentSessionId;
|
|
100
|
+
const stored = s.deviceName && !/ on /.test(s.deviceName);
|
|
101
|
+
const detected = stored
|
|
102
|
+
? { deviceName: s.deviceName, browser: s.browser, os: s.os }
|
|
103
|
+
: s.userAgent
|
|
104
|
+
? (0, requestInfo_1.describeDevice)(s.userAgent)
|
|
105
|
+
: { deviceName: "Unknown device", browser: s.browser, os: s.os };
|
|
106
|
+
const ip = (0, requestInfo_1.normalizeIp)(s.ipAddress);
|
|
107
|
+
const realIp = ip && !(0, requestInfo_1.isPrivateIp)(ip) ? ip : undefined;
|
|
108
|
+
const lastActive = s.lastActiveAt ? new Date(s.lastActiveAt).getTime() : 0;
|
|
109
|
+
return {
|
|
110
|
+
_id: String(s._id),
|
|
111
|
+
sessionId: s.sessionId,
|
|
112
|
+
deviceName: s.customName || detected.deviceName,
|
|
113
|
+
detectedName: detected.deviceName,
|
|
114
|
+
customName: s.customName || undefined,
|
|
115
|
+
browser: detected.browser || undefined,
|
|
116
|
+
os: detected.os || undefined,
|
|
117
|
+
ipAddress: realIp,
|
|
118
|
+
location: realIp ? s.location || undefined : undefined,
|
|
119
|
+
isCurrent: current,
|
|
120
|
+
status: current || Date.now() - lastActive < ACTIVE_WINDOW_MS ? "active" : "idle",
|
|
121
|
+
lastActiveAt: s.lastActiveAt,
|
|
122
|
+
createdAt: s.createdAt,
|
|
123
|
+
expiresAt: s.expiresAt,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** The signed-in user's sessions as the Sessions screen shows them: this device first, then most recently used. */
|
|
127
|
+
async function listSessionViews(SessionModel, userId, currentSessionId) {
|
|
128
|
+
const sessions = await SessionModel.find({ userId, isRevoked: false, expiresAt: { $gt: new Date() } })
|
|
129
|
+
.sort("-lastActiveAt")
|
|
130
|
+
.lean();
|
|
131
|
+
const views = sessions.map((s) => sessionView(s, currentSessionId));
|
|
132
|
+
return views.sort((a, b) => Number(b.isCurrent) - Number(a.isCurrent));
|
|
133
|
+
}
|
|
134
|
+
/** Names one of the user's devices (all of that device's sessions, so later sign-ins keep it); "" clears it. */
|
|
135
|
+
async function renameSessionDevice(SessionModel, userId, id, rawName) {
|
|
136
|
+
if (!mongoose_1.Types.ObjectId.isValid(id))
|
|
137
|
+
return null;
|
|
138
|
+
const session = await SessionModel.findOne({ _id: id, userId, isRevoked: false });
|
|
139
|
+
if (!session)
|
|
140
|
+
return null;
|
|
141
|
+
const name = (0, requestInfo_1.cleanDeviceName)(rawName);
|
|
142
|
+
const filter = session.fingerprintId ? { userId, fingerprintId: session.fingerprintId } : { _id: session._id };
|
|
143
|
+
await SessionModel.updateMany(filter, name ? { $set: { customName: name } } : { $unset: { customName: 1 } });
|
|
144
|
+
return { name };
|
|
145
|
+
}
|
|
146
|
+
/** The signed-in user's open sessions, naming a device, and revoking a session. The backend's protect middleware
|
|
147
|
+
* sets req.sessionId (the JWT's session) so "This device" is marked here, not guessed in the browser. */
|
|
46
148
|
function createSessionHandlers() {
|
|
47
149
|
const SessionModel = session_model_1.Session;
|
|
48
150
|
const getSessions = (0, _http_1.catchAsync)(async (req, res) => {
|
|
49
|
-
const sessions = await SessionModel
|
|
151
|
+
const sessions = await listSessionViews(SessionModel, req.user._id, req.sessionId);
|
|
50
152
|
res.status(_http_1.HTTP.OK).json({ success: true, sessions });
|
|
51
153
|
});
|
|
154
|
+
const renameSession = (0, _http_1.catchAsync)(async (req, res, next) => {
|
|
155
|
+
var _a;
|
|
156
|
+
const result = await renameSessionDevice(SessionModel, req.user._id, req.params.sessionId, (_a = req.body) === null || _a === void 0 ? void 0 : _a.name);
|
|
157
|
+
if (!result)
|
|
158
|
+
return next(new errors_1.AppError("Session not found", _http_1.HTTP.NOT_FOUND));
|
|
159
|
+
res.status(_http_1.HTTP.OK).json({
|
|
160
|
+
success: true,
|
|
161
|
+
message: result.name ? "Device renamed" : "Device name removed",
|
|
162
|
+
name: result.name,
|
|
163
|
+
});
|
|
164
|
+
});
|
|
52
165
|
const revokeSession = (0, _http_1.catchAsync)(async (req, res, next) => {
|
|
166
|
+
if (!mongoose_1.Types.ObjectId.isValid(req.params.sessionId))
|
|
167
|
+
return next(new errors_1.AppError("Session not found", _http_1.HTTP.NOT_FOUND));
|
|
53
168
|
const session = await SessionModel.findOne({ _id: req.params.sessionId, userId: req.user._id });
|
|
54
169
|
if (!session)
|
|
55
170
|
return next(new errors_1.AppError("Session not found", _http_1.HTTP.NOT_FOUND));
|
|
@@ -57,5 +172,5 @@ function createSessionHandlers() {
|
|
|
57
172
|
await session.save();
|
|
58
173
|
res.status(_http_1.HTTP.OK).json({ success: true, message: "Session revoked" });
|
|
59
174
|
});
|
|
60
|
-
return { getSessions, revokeSession };
|
|
175
|
+
return { getSessions, renameSession, revokeSession };
|
|
61
176
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ import { ActivityLog } from "./models/activityLog.model";
|
|
|
47
47
|
import { recordActivity, activityRecorder, clientIp } from "./activity/recorder";
|
|
48
48
|
import type { ActivityEntry, ActivityRule, ActivityActor, ActivityContext, ActivityRecorderOptions } from "./activity/recorder";
|
|
49
49
|
import { Update } from "./models/update.model";
|
|
50
|
-
import { resolveTicketRouting, pickFromGroup, OPEN_TICKET_STATUSES } from "./routing/ticketRouting";
|
|
50
|
+
import { resolveTicketRouting, pickFromGroup, pickFromTicketTeam, ticketTeamMembers, OPEN_TICKET_STATUSES } from "./routing/ticketRouting";
|
|
51
51
|
import { IChat } from "./interfaces/chat.interface";
|
|
52
52
|
import { IMacro, SCRIPT_ANSWER_FIELDS, ScriptAnswerField } from "./interfaces/macro.interface";
|
|
53
53
|
import { IVertical } from "./interfaces/vertical.interface";
|
|
@@ -81,8 +81,8 @@ import { ILoginOtp } from "./interfaces/loginOtp.interface";
|
|
|
81
81
|
import { IEmployee } from "./interfaces/employee.interface";
|
|
82
82
|
import { ICallSession, CallSessionStatus, CallSessionDirection } from "./interfaces/callSession.interface";
|
|
83
83
|
import { IRequest, IRequestAttachment, IRequestMessage, IRequestActivityEntry, IRequestField, RequestCategory, RequestStatus, REQUEST_CATEGORIES, REQUEST_SUBCATEGORIES_BY_CATEGORY } from "./interfaces/request.interface";
|
|
84
|
-
import { ITicket, ITicketAttachment, ITicketActivityEntry, ITicketMessage, TicketCategory, ClientTicketCategory, ClientTicketCategoryLegacy, PartnerTicketCategory, PartnerTicketCategoryLegacy, TicketOwnerType, TicketSource, TicketStatus, TicketPriority, TICKET_STATUS_CLIENT_VIEW, CLIENT_TICKET_CATEGORIES, CLIENT_TICKET_CATEGORIES_LEGACY, PARTNER_TICKET_CATEGORIES, PARTNER_TICKET_CATEGORIES_LEGACY } from "./interfaces/ticket.interface";
|
|
85
|
-
import { TicketCategoryOption, TicketSubCategoryOption, CLIENT_TICKET_CATEGORY_OPTIONS, PARTNER_TICKET_CATEGORY_OPTIONS, CLIENT_TICKET_CATEGORY_OPTIONS_LEGACY, PARTNER_TICKET_CATEGORY_OPTIONS_LEGACY, ALL_TICKET_CATEGORY_OPTIONS, findTicketCategoryOption, EDITABLE_SUBCATEGORY_KEYS, applySubCategoryOverrides } from "./constants/ticketCategories";
|
|
84
|
+
import { ITicket, ITicketAttachment, ITicketActivityEntry, ITicketMessage, TicketCategory, ClientTicketCategory, ClientTicketCategoryLegacy, PartnerTicketCategory, PartnerTicketCategoryLegacy, TicketOwnerType, TicketSource, TicketStatus, TicketPriority, TICKET_STATUS_CLIENT_VIEW, CLIENT_TICKET_CATEGORIES, CLIENT_TICKET_CATEGORIES_LEGACY, PARTNER_TICKET_CATEGORIES, PARTNER_TICKET_CATEGORIES_LEGACY, TicketTeam, TicketTeamMembership, TICKET_TEAMS, TICKET_TEAM_LABELS } from "./interfaces/ticket.interface";
|
|
85
|
+
import { TicketCategoryOption, TicketSubCategoryOption, CLIENT_TICKET_CATEGORY_OPTIONS, PARTNER_TICKET_CATEGORY_OPTIONS, CLIENT_TICKET_CATEGORY_OPTIONS_LEGACY, PARTNER_TICKET_CATEGORY_OPTIONS_LEGACY, ALL_TICKET_CATEGORY_OPTIONS, findTicketCategoryOption, findTicketCategoryOptionFor, ticketCategoryOptionsFor, ticketTeamFor, EDITABLE_SUBCATEGORY_KEYS, applySubCategoryOverrides } from "./constants/ticketCategories";
|
|
86
86
|
import { ITicketSubCategoryOverride } from "./interfaces/ticketCategoryOverride.interface";
|
|
87
87
|
import { TicketSubCategoryOverride } from "./models/ticketCategoryOverride.model";
|
|
88
88
|
import { IRole } from "./interfaces/role.interface";
|
|
@@ -103,8 +103,8 @@ import { clientTree } from "./permissions/trees/client.tree";
|
|
|
103
103
|
import { getTree, getAllKeys, getParentKey, getAncestorKeys } from "./permissions/treeUtils";
|
|
104
104
|
import { resolveEffectivePermissions, hasPermission, validateGrantedKeys, validateExtraKeys, getFullAccessKeys, PermissionSource, ValidationResult } from "./permissions/resolve";
|
|
105
105
|
import { roleSeeds, RoleSeed } from "./permissions/seeds/roles.seed";
|
|
106
|
-
export { Chat, Message, User, Vertical, Macro, Partner, Company, CompanySettings, Review, Wallet, StripeLog, Transaction, Lead, TierConfig, TierProgress, MonthlyTierSnapshot, Product, Plan, PlanOption, Addon, Subscription, Coupon, Visitor, Group, Agent, LeadLedger, Invoice, LeadDispute, Session, LoginOtp, Counter, Employee, CallSession, Request, REQUEST_CATEGORIES, REQUEST_SUBCATEGORIES_BY_CATEGORY, Ticket, EmailSenderMap, CLIENT_TICKET_CATEGORIES, CLIENT_TICKET_CATEGORIES_LEGACY, PARTNER_TICKET_CATEGORIES, PARTNER_TICKET_CATEGORIES_LEGACY, CLIENT_TICKET_CATEGORY_OPTIONS, PARTNER_TICKET_CATEGORY_OPTIONS, CLIENT_TICKET_CATEGORY_OPTIONS_LEGACY, PARTNER_TICKET_CATEGORY_OPTIONS_LEGACY, ALL_TICKET_CATEGORY_OPTIONS, findTicketCategoryOption, EDITABLE_SUBCATEGORY_KEYS, applySubCategoryOverrides, TicketSubCategoryOverride, TICKET_STATUS_CLIENT_VIEW, sanitizeTicketForRequester, Role, AiSummarySettings, AiSummaryUsage, RetainerContract, Retainer, AppointmentCalendar, Appointment, ActivityLog, recordActivity, activityRecorder, clientIp, AuditTask, Update, updateEvents, resolveTicketRouting, pickFromGroup, OPEN_TICKET_STATUSES, SCRIPT_ANSWER_FIELDS, opsTree, employeeTree, partnerTree, clientTree, DASHBOARDS, getTree, getAllKeys, getParentKey, getAncestorKeys, resolveEffectivePermissions, hasPermission, validateGrantedKeys, validateExtraKeys, getFullAccessKeys, roleSeeds, };
|
|
107
|
-
export type { IChat, ScriptAnswerField, IMessage, IUser, IVertical, IMacro, IPartner, ICompany, IOnboardingStep, ITwilioConfig, ICompanySettings, ICallConnectSettings, ILeadConfig, ILeadFields, IRetainerConfig, IDashboardTheme, IReview, IReviewStatusHistoryEntry, IWallet, IStripeLog, ITransaction, ILead, ITierConfig, ITierProgress, IMonthlyTierSnapshot, IProduct, IPlan, IPlanOption, IAddon, ISubscription, ICoupon, CouponDiscountType, IVisitor, IGroup, IAgent, ILeadLedger, IInvoice, ILeadDispute, ISession, ILoginOtp, IEmployee, ICallSession, CallSessionStatus, CallSessionDirection, IRequest, IRequestAttachment, IRequestMessage, IRequestActivityEntry, IRequestField, RequestCategory, RequestStatus, ITicket, ITicketAttachment, ITicketActivityEntry, ITicketMessage, IEmailSenderMap, TicketCategory, ClientTicketCategory, ClientTicketCategoryLegacy, PartnerTicketCategory, PartnerTicketCategoryLegacy, TicketCategoryOption, TicketSubCategoryOption, TicketOwnerType, TicketSource, TicketStatus, TicketPriority, ITicketSubCategoryOverride, IRole, IAiSummarySettings, IAiSummaryExample, IAiSummaryUsage, IRetainerContract, IRetainerContractField, IRetainer, IRetainerFieldValue, RetainerProvider, RetainerContractStatus, RetainerStatus, RetainerDeliveryMode, IAppointmentCalendar, IAppointment, AppointmentCalendarStatus, AppointmentStatus, IActivityLog, IActivityChange, ActivityActorKind, ActivityDashboard, ActivityOutcome, ActivityEntry, ActivityRule, ActivityActor, ActivityContext, ActivityRecorderOptions, AiSummaryLength, IAuditTask, AuditTaskType, AuditTaskStatus, ILeadAudit, LeadAuditDecision, LeadAuditReviewStatus, IUpdate, UpdateDashboard, UpdateAudience, UpdateType, TicketRoutingInput, TicketRoutingResult, Dashboard, PermissionNode, PermissionSource, ValidationResult, RoleSeed, };
|
|
106
|
+
export { Chat, Message, User, Vertical, Macro, Partner, Company, CompanySettings, Review, Wallet, StripeLog, Transaction, Lead, TierConfig, TierProgress, MonthlyTierSnapshot, Product, Plan, PlanOption, Addon, Subscription, Coupon, Visitor, Group, Agent, LeadLedger, Invoice, LeadDispute, Session, LoginOtp, Counter, Employee, CallSession, Request, REQUEST_CATEGORIES, REQUEST_SUBCATEGORIES_BY_CATEGORY, Ticket, EmailSenderMap, CLIENT_TICKET_CATEGORIES, CLIENT_TICKET_CATEGORIES_LEGACY, PARTNER_TICKET_CATEGORIES, PARTNER_TICKET_CATEGORIES_LEGACY, CLIENT_TICKET_CATEGORY_OPTIONS, PARTNER_TICKET_CATEGORY_OPTIONS, CLIENT_TICKET_CATEGORY_OPTIONS_LEGACY, PARTNER_TICKET_CATEGORY_OPTIONS_LEGACY, ALL_TICKET_CATEGORY_OPTIONS, findTicketCategoryOption, findTicketCategoryOptionFor, ticketCategoryOptionsFor, ticketTeamFor, TICKET_TEAMS, TICKET_TEAM_LABELS, EDITABLE_SUBCATEGORY_KEYS, applySubCategoryOverrides, TicketSubCategoryOverride, TICKET_STATUS_CLIENT_VIEW, sanitizeTicketForRequester, Role, AiSummarySettings, AiSummaryUsage, RetainerContract, Retainer, AppointmentCalendar, Appointment, ActivityLog, recordActivity, activityRecorder, clientIp, AuditTask, Update, updateEvents, resolveTicketRouting, pickFromGroup, pickFromTicketTeam, ticketTeamMembers, OPEN_TICKET_STATUSES, SCRIPT_ANSWER_FIELDS, opsTree, employeeTree, partnerTree, clientTree, DASHBOARDS, getTree, getAllKeys, getParentKey, getAncestorKeys, resolveEffectivePermissions, hasPermission, validateGrantedKeys, validateExtraKeys, getFullAccessKeys, roleSeeds, };
|
|
107
|
+
export type { IChat, ScriptAnswerField, IMessage, IUser, IVertical, IMacro, IPartner, ICompany, IOnboardingStep, ITwilioConfig, ICompanySettings, ICallConnectSettings, ILeadConfig, ILeadFields, IRetainerConfig, IDashboardTheme, IReview, IReviewStatusHistoryEntry, IWallet, IStripeLog, ITransaction, ILead, ITierConfig, ITierProgress, IMonthlyTierSnapshot, IProduct, IPlan, IPlanOption, IAddon, ISubscription, ICoupon, CouponDiscountType, IVisitor, IGroup, IAgent, ILeadLedger, IInvoice, ILeadDispute, ISession, ILoginOtp, IEmployee, ICallSession, CallSessionStatus, CallSessionDirection, IRequest, IRequestAttachment, IRequestMessage, IRequestActivityEntry, IRequestField, RequestCategory, RequestStatus, ITicket, ITicketAttachment, ITicketActivityEntry, ITicketMessage, IEmailSenderMap, TicketCategory, ClientTicketCategory, ClientTicketCategoryLegacy, PartnerTicketCategory, PartnerTicketCategoryLegacy, TicketTeam, TicketTeamMembership, TicketCategoryOption, TicketSubCategoryOption, TicketOwnerType, TicketSource, TicketStatus, TicketPriority, ITicketSubCategoryOverride, IRole, IAiSummarySettings, IAiSummaryExample, IAiSummaryUsage, IRetainerContract, IRetainerContractField, IRetainer, IRetainerFieldValue, RetainerProvider, RetainerContractStatus, RetainerStatus, RetainerDeliveryMode, IAppointmentCalendar, IAppointment, AppointmentCalendarStatus, AppointmentStatus, IActivityLog, IActivityChange, ActivityActorKind, ActivityDashboard, ActivityOutcome, ActivityEntry, ActivityRule, ActivityActor, ActivityContext, ActivityRecorderOptions, AiSummaryLength, IAuditTask, AuditTaskType, AuditTaskStatus, ILeadAudit, LeadAuditDecision, LeadAuditReviewStatus, IUpdate, UpdateDashboard, UpdateAudience, UpdateType, TicketRoutingInput, TicketRoutingResult, Dashboard, PermissionNode, PermissionSource, ValidationResult, RoleSeed, };
|
|
108
108
|
export * from "./helpers/errors";
|
|
109
109
|
export * from "./helpers/listQuery";
|
|
110
110
|
export * from "./helpers/chatAttachments";
|
|
@@ -117,6 +117,8 @@ export * from "./helpers/avatars";
|
|
|
117
117
|
export * from "./helpers/myUpdates";
|
|
118
118
|
export * from "./helpers/ownActivity";
|
|
119
119
|
export * from "./helpers/sessions";
|
|
120
|
+
export { normalizeIp, isPrivateIp, requestLocation, describeDevice, cleanDeviceName } from "./helpers/requestInfo";
|
|
121
|
+
export type { DeviceHints, DeviceDescription } from "./helpers/requestInfo";
|
|
120
122
|
export * from "./helpers/invoiceDocument";
|
|
121
123
|
export * from "./helpers/ownTickets";
|
|
122
124
|
//# sourceMappingURL=index.d.ts.map
|
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
|
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
exports.roleSeeds = exports.getFullAccessKeys = exports.validateExtraKeys = exports.validateGrantedKeys = exports.hasPermission = exports.resolveEffectivePermissions = exports.getAncestorKeys = exports.getParentKey = exports.getAllKeys = exports.getTree = exports.DASHBOARDS = exports.clientTree = exports.partnerTree = exports.employeeTree = exports.opsTree = exports.SCRIPT_ANSWER_FIELDS = exports.OPEN_TICKET_STATUSES = exports.pickFromGroup = exports.resolveTicketRouting = exports.updateEvents = exports.Update = exports.AuditTask = exports.clientIp = exports.activityRecorder = exports.recordActivity = exports.ActivityLog = exports.Appointment = exports.AppointmentCalendar = exports.Retainer = exports.RetainerContract = exports.AiSummaryUsage = exports.AiSummarySettings = exports.Role = exports.sanitizeTicketForRequester = exports.TICKET_STATUS_CLIENT_VIEW = exports.TicketSubCategoryOverride = void 0;
|
|
17
|
+
exports.ticketCategoryOptionsFor = exports.findTicketCategoryOptionFor = exports.findTicketCategoryOption = exports.ALL_TICKET_CATEGORY_OPTIONS = exports.PARTNER_TICKET_CATEGORY_OPTIONS_LEGACY = exports.CLIENT_TICKET_CATEGORY_OPTIONS_LEGACY = exports.PARTNER_TICKET_CATEGORY_OPTIONS = exports.CLIENT_TICKET_CATEGORY_OPTIONS = exports.PARTNER_TICKET_CATEGORIES_LEGACY = exports.PARTNER_TICKET_CATEGORIES = exports.CLIENT_TICKET_CATEGORIES_LEGACY = exports.CLIENT_TICKET_CATEGORIES = exports.EmailSenderMap = exports.Ticket = exports.REQUEST_SUBCATEGORIES_BY_CATEGORY = exports.REQUEST_CATEGORIES = exports.Request = exports.CallSession = exports.Employee = exports.Counter = exports.LoginOtp = exports.Session = exports.LeadDispute = exports.Invoice = exports.LeadLedger = exports.Agent = exports.Group = exports.Visitor = exports.Coupon = exports.Subscription = exports.Addon = exports.PlanOption = exports.Plan = exports.Product = exports.MonthlyTierSnapshot = exports.TierProgress = exports.TierConfig = exports.Lead = exports.Transaction = exports.StripeLog = exports.Wallet = exports.Review = exports.CompanySettings = exports.Company = exports.Partner = exports.Macro = exports.Vertical = exports.User = exports.Message = exports.Chat = void 0;
|
|
18
|
+
exports.cleanDeviceName = exports.describeDevice = exports.requestLocation = exports.isPrivateIp = exports.normalizeIp = exports.roleSeeds = exports.getFullAccessKeys = exports.validateExtraKeys = exports.validateGrantedKeys = exports.hasPermission = exports.resolveEffectivePermissions = exports.getAncestorKeys = exports.getParentKey = exports.getAllKeys = exports.getTree = exports.DASHBOARDS = exports.clientTree = exports.partnerTree = exports.employeeTree = exports.opsTree = exports.SCRIPT_ANSWER_FIELDS = exports.OPEN_TICKET_STATUSES = exports.ticketTeamMembers = exports.pickFromTicketTeam = exports.pickFromGroup = exports.resolveTicketRouting = exports.updateEvents = exports.Update = exports.AuditTask = exports.clientIp = exports.activityRecorder = exports.recordActivity = exports.ActivityLog = exports.Appointment = exports.AppointmentCalendar = exports.Retainer = exports.RetainerContract = exports.AiSummaryUsage = exports.AiSummarySettings = exports.Role = exports.sanitizeTicketForRequester = exports.TICKET_STATUS_CLIENT_VIEW = exports.TicketSubCategoryOverride = exports.applySubCategoryOverrides = exports.EDITABLE_SUBCATEGORY_KEYS = exports.TICKET_TEAM_LABELS = exports.TICKET_TEAMS = exports.ticketTeamFor = void 0;
|
|
19
19
|
// MODELS
|
|
20
20
|
const chat_model_1 = require("./models/chat.model");
|
|
21
21
|
Object.defineProperty(exports, "Chat", { enumerable: true, get: function () { return chat_model_1.Chat; } });
|
|
@@ -116,6 +116,8 @@ Object.defineProperty(exports, "Update", { enumerable: true, get: function () {
|
|
|
116
116
|
const ticketRouting_1 = require("./routing/ticketRouting");
|
|
117
117
|
Object.defineProperty(exports, "resolveTicketRouting", { enumerable: true, get: function () { return ticketRouting_1.resolveTicketRouting; } });
|
|
118
118
|
Object.defineProperty(exports, "pickFromGroup", { enumerable: true, get: function () { return ticketRouting_1.pickFromGroup; } });
|
|
119
|
+
Object.defineProperty(exports, "pickFromTicketTeam", { enumerable: true, get: function () { return ticketRouting_1.pickFromTicketTeam; } });
|
|
120
|
+
Object.defineProperty(exports, "ticketTeamMembers", { enumerable: true, get: function () { return ticketRouting_1.ticketTeamMembers; } });
|
|
119
121
|
Object.defineProperty(exports, "OPEN_TICKET_STATUSES", { enumerable: true, get: function () { return ticketRouting_1.OPEN_TICKET_STATUSES; } });
|
|
120
122
|
const macro_interface_1 = require("./interfaces/macro.interface");
|
|
121
123
|
Object.defineProperty(exports, "SCRIPT_ANSWER_FIELDS", { enumerable: true, get: function () { return macro_interface_1.SCRIPT_ANSWER_FIELDS; } });
|
|
@@ -128,6 +130,8 @@ Object.defineProperty(exports, "CLIENT_TICKET_CATEGORIES", { enumerable: true, g
|
|
|
128
130
|
Object.defineProperty(exports, "CLIENT_TICKET_CATEGORIES_LEGACY", { enumerable: true, get: function () { return ticket_interface_1.CLIENT_TICKET_CATEGORIES_LEGACY; } });
|
|
129
131
|
Object.defineProperty(exports, "PARTNER_TICKET_CATEGORIES", { enumerable: true, get: function () { return ticket_interface_1.PARTNER_TICKET_CATEGORIES; } });
|
|
130
132
|
Object.defineProperty(exports, "PARTNER_TICKET_CATEGORIES_LEGACY", { enumerable: true, get: function () { return ticket_interface_1.PARTNER_TICKET_CATEGORIES_LEGACY; } });
|
|
133
|
+
Object.defineProperty(exports, "TICKET_TEAMS", { enumerable: true, get: function () { return ticket_interface_1.TICKET_TEAMS; } });
|
|
134
|
+
Object.defineProperty(exports, "TICKET_TEAM_LABELS", { enumerable: true, get: function () { return ticket_interface_1.TICKET_TEAM_LABELS; } });
|
|
131
135
|
const ticketCategories_1 = require("./constants/ticketCategories");
|
|
132
136
|
Object.defineProperty(exports, "CLIENT_TICKET_CATEGORY_OPTIONS", { enumerable: true, get: function () { return ticketCategories_1.CLIENT_TICKET_CATEGORY_OPTIONS; } });
|
|
133
137
|
Object.defineProperty(exports, "PARTNER_TICKET_CATEGORY_OPTIONS", { enumerable: true, get: function () { return ticketCategories_1.PARTNER_TICKET_CATEGORY_OPTIONS; } });
|
|
@@ -135,6 +139,9 @@ Object.defineProperty(exports, "CLIENT_TICKET_CATEGORY_OPTIONS_LEGACY", { enumer
|
|
|
135
139
|
Object.defineProperty(exports, "PARTNER_TICKET_CATEGORY_OPTIONS_LEGACY", { enumerable: true, get: function () { return ticketCategories_1.PARTNER_TICKET_CATEGORY_OPTIONS_LEGACY; } });
|
|
136
140
|
Object.defineProperty(exports, "ALL_TICKET_CATEGORY_OPTIONS", { enumerable: true, get: function () { return ticketCategories_1.ALL_TICKET_CATEGORY_OPTIONS; } });
|
|
137
141
|
Object.defineProperty(exports, "findTicketCategoryOption", { enumerable: true, get: function () { return ticketCategories_1.findTicketCategoryOption; } });
|
|
142
|
+
Object.defineProperty(exports, "findTicketCategoryOptionFor", { enumerable: true, get: function () { return ticketCategories_1.findTicketCategoryOptionFor; } });
|
|
143
|
+
Object.defineProperty(exports, "ticketCategoryOptionsFor", { enumerable: true, get: function () { return ticketCategories_1.ticketCategoryOptionsFor; } });
|
|
144
|
+
Object.defineProperty(exports, "ticketTeamFor", { enumerable: true, get: function () { return ticketCategories_1.ticketTeamFor; } });
|
|
138
145
|
Object.defineProperty(exports, "EDITABLE_SUBCATEGORY_KEYS", { enumerable: true, get: function () { return ticketCategories_1.EDITABLE_SUBCATEGORY_KEYS; } });
|
|
139
146
|
Object.defineProperty(exports, "applySubCategoryOverrides", { enumerable: true, get: function () { return ticketCategories_1.applySubCategoryOverrides; } });
|
|
140
147
|
const ticketCategoryOverride_model_1 = require("./models/ticketCategoryOverride.model");
|
|
@@ -180,5 +187,11 @@ __exportStar(require("./helpers/avatars"), exports);
|
|
|
180
187
|
__exportStar(require("./helpers/myUpdates"), exports);
|
|
181
188
|
__exportStar(require("./helpers/ownActivity"), exports);
|
|
182
189
|
__exportStar(require("./helpers/sessions"), exports);
|
|
190
|
+
var requestInfo_1 = require("./helpers/requestInfo");
|
|
191
|
+
Object.defineProperty(exports, "normalizeIp", { enumerable: true, get: function () { return requestInfo_1.normalizeIp; } });
|
|
192
|
+
Object.defineProperty(exports, "isPrivateIp", { enumerable: true, get: function () { return requestInfo_1.isPrivateIp; } });
|
|
193
|
+
Object.defineProperty(exports, "requestLocation", { enumerable: true, get: function () { return requestInfo_1.requestLocation; } });
|
|
194
|
+
Object.defineProperty(exports, "describeDevice", { enumerable: true, get: function () { return requestInfo_1.describeDevice; } });
|
|
195
|
+
Object.defineProperty(exports, "cleanDeviceName", { enumerable: true, get: function () { return requestInfo_1.cleanDeviceName; } });
|
|
183
196
|
__exportStar(require("./helpers/invoiceDocument"), exports);
|
|
184
197
|
__exportStar(require("./helpers/ownTickets"), exports);
|