@botfabrik/engine-webclient 4.93.2 → 4.93.4
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/client/assets/{index-DBZImkhZ.js → index-Y-O4sres.js} +87 -87
- package/dist/client/assets/index-Y-O4sres.js.map +1 -0
- package/dist/client/index.html +1 -1
- package/dist/createSessionInfo.test.js +1 -6
- package/dist/index.d.ts +0 -6
- package/dist/index.js +15 -80
- package/dist/requestSessionData.d.ts +1 -0
- package/dist/requestSessionData.js +5 -0
- package/dist/requestSessionData.test.js +16 -9
- package/package.json +2 -4
- package/dist/client/assets/index-DBZImkhZ.js.map +0 -1
package/dist/client/index.html
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<meta name="theme-color" content="#000000" />
|
|
14
14
|
<meta name="google" content="notranslate" />
|
|
15
15
|
<title>Bubble Chat Client</title>
|
|
16
|
-
<script type="module" crossorigin src="./assets/index-
|
|
16
|
+
<script type="module" crossorigin src="./assets/index-Y-O4sres.js"></script>
|
|
17
17
|
<link rel="stylesheet" crossorigin href="./assets/index-CQifi_K_.css">
|
|
18
18
|
</head>
|
|
19
19
|
|
|
@@ -6,9 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const globals_1 = require("@jest/globals");
|
|
7
7
|
const createSessionInfo_1 = __importDefault(require("./createSessionInfo"));
|
|
8
8
|
(0, globals_1.describe)('create session info', () => {
|
|
9
|
-
const props = {
|
|
10
|
-
sessionTokenSecret: 'some-secret',
|
|
11
|
-
};
|
|
12
9
|
const querystrings = {};
|
|
13
10
|
const headers = {
|
|
14
11
|
host: 'fluance-chatbot.scapp.io',
|
|
@@ -46,7 +43,7 @@ const createSessionInfo_1 = __importDefault(require("./createSessionInfo"));
|
|
|
46
43
|
environment: 'PROD',
|
|
47
44
|
};
|
|
48
45
|
(0, globals_1.it)('without user payload', async () => {
|
|
49
|
-
const sessionInfo = await (0, createSessionInfo_1.default)(socket, 'my-client', 'TEST', defaultSessionInfo, 'my-user-id', 'de_DE', { email: 'hans@example.com' },
|
|
46
|
+
const sessionInfo = await (0, createSessionInfo_1.default)(socket, 'my-client', 'TEST', defaultSessionInfo, 'my-user-id', 'de_DE', { email: 'hans@example.com' }, {})();
|
|
50
47
|
// client
|
|
51
48
|
(0, globals_1.expect)(sessionInfo.client.name).toBe('my-client');
|
|
52
49
|
(0, globals_1.expect)(sessionInfo.client.type).toBe('webclient');
|
|
@@ -73,7 +70,6 @@ const createSessionInfo_1 = __importDefault(require("./createSessionInfo"));
|
|
|
73
70
|
};
|
|
74
71
|
const props = {
|
|
75
72
|
requestUserInfos,
|
|
76
|
-
sessionTokenSecret: 'some-secret',
|
|
77
73
|
};
|
|
78
74
|
const sessionInfo = await (0, createSessionInfo_1.default)(socket, 'my-client', 'TEST', defaultSessionInfo, 'my-user-id', 'de_DE', {}, props)();
|
|
79
75
|
(0, globals_1.expect)(sessionInfo.user.id).toBe('hans.muster@PRIMARY');
|
|
@@ -88,7 +84,6 @@ const createSessionInfo_1 = __importDefault(require("./createSessionInfo"));
|
|
|
88
84
|
};
|
|
89
85
|
const props = {
|
|
90
86
|
requestUserInfos,
|
|
91
|
-
sessionTokenSecret: 'some-secret',
|
|
92
87
|
};
|
|
93
88
|
const sessionInfo = await (0, createSessionInfo_1.default)(socket, 'my-client', 'TEST', defaultSessionInfo, 'my-user-id', 'de_DE', {}, props)();
|
|
94
89
|
(0, globals_1.expect)(sessionInfo.user.id).toBe('my-user-id');
|
package/dist/index.d.ts
CHANGED
|
@@ -13,12 +13,6 @@ export interface WebClientProps {
|
|
|
13
13
|
speech?: SpeechToTextProps | undefined;
|
|
14
14
|
expandChatWindowAtStart?: Devices;
|
|
15
15
|
fabVisible?: boolean;
|
|
16
|
-
/**
|
|
17
|
-
* A secret key used to generate and verify session tokens (e.g. HMAC).
|
|
18
|
-
* Should be long, random, and stored securely (e.g. via environment variable).
|
|
19
|
-
* Used for signing tokens that identify sessions over insecure channels like WebSocket.
|
|
20
|
-
*/
|
|
21
|
-
sessionTokenSecret: string;
|
|
22
16
|
/**
|
|
23
17
|
* Displays a start screen before a new chat begins, useful for user opt-in (e.g., terms acceptance).
|
|
24
18
|
* Contains a text (`start-screen.intro` in Markdown), form fields, and a start button (`start-screen.start-chat`).
|
package/dist/index.js
CHANGED
|
@@ -6,9 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.CLIENT_TYPE = exports.Devices = void 0;
|
|
7
7
|
const engine_domain_1 = require("@botfabrik/engine-domain");
|
|
8
8
|
const engine_transcript_export_1 = require("@botfabrik/engine-transcript-export");
|
|
9
|
-
const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
10
|
-
const crypto_1 = require("crypto");
|
|
11
9
|
const express_1 = require("express");
|
|
10
|
+
const node_crypto_1 = require("node:crypto");
|
|
12
11
|
const package_json_1 = require("../package.json");
|
|
13
12
|
const createSessionInfo_1 = __importDefault(require("./createSessionInfo"));
|
|
14
13
|
const extractLocale_1 = __importDefault(require("./extractLocale"));
|
|
@@ -19,6 +18,8 @@ const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
|
19
18
|
const setTranslations_1 = __importDefault(require("./setTranslations"));
|
|
20
19
|
const speechToText_1 = __importDefault(require("./speechToText"));
|
|
21
20
|
const views_1 = __importDefault(require("./views"));
|
|
21
|
+
const SESSION_ID_COOKIE_NAME = 'session-id';
|
|
22
|
+
const USER_ID_COOKIE_NAME = 'user-id';
|
|
22
23
|
var Devices;
|
|
23
24
|
(function (Devices) {
|
|
24
25
|
Devices["All"] = "all";
|
|
@@ -26,15 +27,11 @@ var Devices;
|
|
|
26
27
|
Devices["Desktop"] = "desktop";
|
|
27
28
|
Devices["None"] = "none";
|
|
28
29
|
})(Devices || (exports.Devices = Devices = {}));
|
|
29
|
-
const SESSION_ID_COOKIE_NAME = 'session-id';
|
|
30
|
-
const USER_ID_COOKIE_NAME = 'user-id';
|
|
31
30
|
exports.default = (clientName, environment, props) => async (bot) => {
|
|
32
31
|
const logger = bot.logger.child({ clientType: exports.CLIENT_TYPE, clientName });
|
|
33
|
-
bot.webserver.express.use((0, cookie_parser_1.default)());
|
|
34
32
|
// serve transcript pdf
|
|
35
|
-
bot.webserver.express.
|
|
36
|
-
const
|
|
37
|
-
const sessionId = cookies[SESSION_ID_COOKIE_NAME];
|
|
33
|
+
bot.webserver.express.use('/transcript-pdf/:sessionId', async (req, res) => {
|
|
34
|
+
const sessionId = req.params['sessionId'];
|
|
38
35
|
if (sessionId?.length) {
|
|
39
36
|
const session = await bot.createSession(sessionId);
|
|
40
37
|
const pdf = await (0, engine_transcript_export_1.getPdf)(session);
|
|
@@ -67,25 +64,19 @@ exports.default = (clientName, environment, props) => async (bot) => {
|
|
|
67
64
|
});
|
|
68
65
|
}
|
|
69
66
|
bot.webserver.express.use(`/${clientName}/embed`, (0, express_1.static)(__dirname + '/embed', serveStaticOptions));
|
|
67
|
+
// TODO: remove in future versions
|
|
70
68
|
bot.webserver.express.get(`/${clientName}/me/session`, (req, res) => {
|
|
69
|
+
logger.info('Old client access get token');
|
|
71
70
|
const cookies = req.cookies || {};
|
|
72
|
-
const sessionId = cookies[SESSION_ID_COOKIE_NAME] || (0,
|
|
71
|
+
const sessionId = cookies[SESSION_ID_COOKIE_NAME] || (0, node_crypto_1.randomUUID)();
|
|
73
72
|
const userId = cookies[USER_ID_COOKIE_NAME] ||
|
|
74
73
|
cookies['bubble-chat-user-id'] || // TODO: remove in future versions
|
|
75
|
-
(0,
|
|
76
|
-
|
|
77
|
-
const userIdToken = generateSignedToken(userId, props.sessionTokenSecret);
|
|
78
|
-
res.cookie(SESSION_ID_COOKIE_NAME, sessionId, {
|
|
79
|
-
...buildCookieOptions(clientName, bot),
|
|
80
|
-
maxAge: 24 * 60 * 60 * 1000, // 1 day
|
|
81
|
-
});
|
|
82
|
-
if (!cookies[USER_ID_COOKIE_NAME]) {
|
|
83
|
-
res.cookie(USER_ID_COOKIE_NAME, userId, buildCookieOptions(clientName, bot));
|
|
84
|
-
}
|
|
85
|
-
res.status(201).json({ sessionIdToken, userIdToken });
|
|
74
|
+
(0, node_crypto_1.randomUUID)();
|
|
75
|
+
res.status(201).json({ sessionIdToken: sessionId, userIdToken: userId });
|
|
86
76
|
});
|
|
77
|
+
// TODO: remove in future versions
|
|
87
78
|
bot.webserver.express.delete(`/${clientName}/me/session`, (_req, res) => {
|
|
88
|
-
|
|
79
|
+
logger.info('Old client access delete token');
|
|
89
80
|
res.sendStatus(204);
|
|
90
81
|
});
|
|
91
82
|
bot.webserver.express.get(`/${clientName}/logo.svg`, (_req, res) => {
|
|
@@ -143,29 +134,13 @@ const onTerminateSession = (socket, bot) => async ({ sessionId, // passed if the
|
|
|
143
134
|
socket.leave(sessionId);
|
|
144
135
|
await session.dispatch(engine_domain_1.Actions.guestDisconnected(sessionId));
|
|
145
136
|
};
|
|
146
|
-
const onStartChat = (socket, props, bot, clientName, environment, logger) => async ({
|
|
147
|
-
userIdToken, querystrings, }) => {
|
|
137
|
+
const onStartChat = (socket, props, bot, clientName, environment, logger) => async ({ sessionId: sessionIdFromClient, userId: defaultUserId, querystrings, sessionIdToken, userIdToken, }) => {
|
|
148
138
|
const locale = (0, extractLocale_1.default)(querystrings, socket.request.headers['accept-language']);
|
|
149
|
-
let sessionId = verifySignedToken(sessionIdToken, props.sessionTokenSecret);
|
|
150
|
-
let userId = verifySignedToken(userIdToken, props.sessionTokenSecret);
|
|
151
|
-
// TODO: remove temporary code in future versions
|
|
152
|
-
// this code is relevant for old clients
|
|
153
|
-
if (!sessionId && oldSessionId) {
|
|
154
|
-
logger.info(`Received an old session ID from client: ${oldSessionId}. It will be replaced with a new one.`);
|
|
155
|
-
sessionId = oldSessionId;
|
|
156
|
-
}
|
|
157
|
-
if (!userId) {
|
|
158
|
-
userId = (0, crypto_1.randomUUID)();
|
|
159
|
-
}
|
|
160
|
-
if (!sessionId || !userId) {
|
|
161
|
-
logger.error(`Invalid session ID token received from client: ${sessionIdToken}`);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
139
|
const sessionsCollection = bot.store.db.collection('sessions');
|
|
165
|
-
const { sessionInfo: defaultSessionInfo, isNew } = await (0, requestSessionData_1.default)(
|
|
140
|
+
const { sessionId, sessionInfo: defaultSessionInfo, isNew, } = await (0, requestSessionData_1.default)(sessionIdFromClient || sessionIdToken, querystrings, sessionsCollection, clientName, props);
|
|
166
141
|
// create a channel for each session
|
|
167
142
|
socket.join(sessionId);
|
|
168
|
-
const sessionInfo = await (0, createSessionInfo_1.default)(socket, clientName, environment, defaultSessionInfo,
|
|
143
|
+
const sessionInfo = await (0, createSessionInfo_1.default)(socket, clientName, environment, defaultSessionInfo, defaultUserId || userIdToken, locale, querystrings, props)();
|
|
169
144
|
const session = await bot.createSession(sessionId, sessionInfo);
|
|
170
145
|
sendConfigurationToClient(socket, props, bot, clientName);
|
|
171
146
|
// sending persisted state to client
|
|
@@ -242,44 +217,4 @@ const sendConfigurationToClient = (socket, props, bot, clientName) => {
|
|
|
242
217
|
});
|
|
243
218
|
}
|
|
244
219
|
};
|
|
245
|
-
const buildCookieOptions = (clientName, bot) => {
|
|
246
|
-
const isLocalhost = bot.webserver.baseUrl === 'http://localhost:3000';
|
|
247
|
-
return {
|
|
248
|
-
httpOnly: true, // 🔒 Not accessible via JS
|
|
249
|
-
secure: !isLocalhost, // ✅ true only for HTTPS
|
|
250
|
-
sameSite: 'none', // Important, if chat-widget runs under a different domain
|
|
251
|
-
path: `/${clientName}`, // Path for the cookie
|
|
252
|
-
};
|
|
253
|
-
};
|
|
254
|
-
/**
|
|
255
|
-
* Generates a signed token.
|
|
256
|
-
*
|
|
257
|
-
* @param payload
|
|
258
|
-
* @param secret
|
|
259
|
-
* @returns token in the format "payload.signature"
|
|
260
|
-
*/
|
|
261
|
-
const generateSignedToken = (payload, secret) => {
|
|
262
|
-
const signature = (0, crypto_1.createHmac)('sha256', secret).update(payload).digest('hex');
|
|
263
|
-
return `${payload}.${signature}`;
|
|
264
|
-
};
|
|
265
|
-
/**
|
|
266
|
-
* Verifies a signed token.
|
|
267
|
-
*
|
|
268
|
-
* @param token in the format "payload.signature"
|
|
269
|
-
* @param secret
|
|
270
|
-
* @returns payload if the token is valid, otherwise null.
|
|
271
|
-
*/
|
|
272
|
-
const verifySignedToken = (token, secret) => {
|
|
273
|
-
if (!token)
|
|
274
|
-
return null;
|
|
275
|
-
const [payload, signature] = token.split('.');
|
|
276
|
-
if (!payload || !signature)
|
|
277
|
-
return null;
|
|
278
|
-
const expectedSignature = (0, crypto_1.createHmac)('sha256', secret)
|
|
279
|
-
.update(payload)
|
|
280
|
-
.digest('hex');
|
|
281
|
-
if (signature !== expectedSignature)
|
|
282
|
-
return null;
|
|
283
|
-
return payload;
|
|
284
|
-
};
|
|
285
220
|
exports.CLIENT_TYPE = 'webclient';
|
|
@@ -2,6 +2,7 @@ import type { SessionInfo } from '@botfabrik/engine-domain';
|
|
|
2
2
|
import { type WebClientProps } from './index';
|
|
3
3
|
import type { SessionInfoClientPayload, SessionInfoUserPayload } from './types';
|
|
4
4
|
interface SessionData {
|
|
5
|
+
sessionId: string;
|
|
5
6
|
sessionInfo: SessionInfo<SessionInfoClientPayload, SessionInfoUserPayload>;
|
|
6
7
|
isNew: boolean;
|
|
7
8
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const crypto_1 = require("crypto");
|
|
3
4
|
const index_1 = require("./index");
|
|
4
5
|
const requestSessionData = async (sessionId, querystrings, sessionsCollection, clientName, props) => {
|
|
5
6
|
const baseQuery = {
|
|
@@ -21,13 +22,16 @@ const requestSessionData = async (sessionId, querystrings, sessionsCollection, c
|
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
24
|
const sessionRecord = await sessionsCollection.findOne(findSessionRecordQuery, { _id: 1, sessionInfo: 1 });
|
|
25
|
+
let sesId;
|
|
24
26
|
let sessionInfo;
|
|
25
27
|
let isNew;
|
|
26
28
|
if (sessionRecord) {
|
|
29
|
+
sesId = sessionRecord._id;
|
|
27
30
|
sessionInfo = sessionRecord.sessionInfo;
|
|
28
31
|
isNew = false;
|
|
29
32
|
}
|
|
30
33
|
else {
|
|
34
|
+
sesId = (0, crypto_1.randomUUID)();
|
|
31
35
|
sessionInfo = {
|
|
32
36
|
client: {},
|
|
33
37
|
user: {},
|
|
@@ -36,6 +40,7 @@ const requestSessionData = async (sessionId, querystrings, sessionsCollection, c
|
|
|
36
40
|
isNew = true;
|
|
37
41
|
}
|
|
38
42
|
return {
|
|
43
|
+
sessionId: sesId,
|
|
39
44
|
sessionInfo,
|
|
40
45
|
isNew,
|
|
41
46
|
};
|
|
@@ -5,13 +5,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const globals_1 = require("@jest/globals");
|
|
7
7
|
const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
8
|
+
globals_1.jest.mock('crypto', () => {
|
|
9
|
+
const original = globals_1.jest.requireActual('crypto');
|
|
10
|
+
return {
|
|
11
|
+
v4: globals_1.jest.fn(() => 'uuid'),
|
|
12
|
+
...original,
|
|
13
|
+
randomUUID: globals_1.jest.fn(() => 'some-uuid'),
|
|
14
|
+
};
|
|
15
|
+
});
|
|
8
16
|
(0, globals_1.describe)('request session id', () => {
|
|
9
17
|
(0, globals_1.beforeEach)(() => {
|
|
10
18
|
globals_1.jest.clearAllMocks();
|
|
11
19
|
});
|
|
12
|
-
const props = {
|
|
13
|
-
sessionTokenSecret: 'some-secret',
|
|
14
|
-
};
|
|
15
20
|
const querystrings = {
|
|
16
21
|
accessToken: 'access-token',
|
|
17
22
|
};
|
|
@@ -21,13 +26,14 @@ const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
|
21
26
|
const sessionsCollection = {
|
|
22
27
|
findOne,
|
|
23
28
|
};
|
|
24
|
-
const { isNew } = await (0, requestSessionData_1.default)('session-id', querystrings, sessionsCollection, 'test-bot',
|
|
29
|
+
const { sessionId, isNew } = await (0, requestSessionData_1.default)('session-id', querystrings, sessionsCollection, 'test-bot', {});
|
|
25
30
|
(0, globals_1.expect)(findOne).toHaveBeenCalledTimes(1);
|
|
26
31
|
(0, globals_1.expect)(findOne).toHaveBeenCalledWith({
|
|
27
32
|
_id: 'session-id',
|
|
28
33
|
'sessionInfo.client.name': 'test-bot',
|
|
29
34
|
'sessionInfo.client.type': 'webclient',
|
|
30
35
|
}, { _id: 1, sessionInfo: 1 });
|
|
36
|
+
(0, globals_1.expect)(sessionId).toBe('some-uuid');
|
|
31
37
|
(0, globals_1.expect)(isNew).toBe(true);
|
|
32
38
|
});
|
|
33
39
|
(0, globals_1.it)('when sessionId has been passed by query param and exists in db', async () => {
|
|
@@ -36,13 +42,14 @@ const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
|
36
42
|
const sessionsCollection = {
|
|
37
43
|
findOne,
|
|
38
44
|
};
|
|
39
|
-
const { isNew } = await (0, requestSessionData_1.default)('session-id', querystrings, sessionsCollection, 'test-bot',
|
|
45
|
+
const { sessionId, isNew } = await (0, requestSessionData_1.default)('session-id', querystrings, sessionsCollection, 'test-bot', {});
|
|
40
46
|
(0, globals_1.expect)(findOne).toHaveBeenCalledTimes(1);
|
|
41
47
|
(0, globals_1.expect)(findOne).toHaveBeenCalledWith({
|
|
42
48
|
_id: 'session-id',
|
|
43
49
|
'sessionInfo.client.name': 'test-bot',
|
|
44
50
|
'sessionInfo.client.type': 'webclient',
|
|
45
51
|
}, { _id: 1, sessionInfo: 1 });
|
|
52
|
+
(0, globals_1.expect)(sessionId).toBe('session-id');
|
|
46
53
|
(0, globals_1.expect)(isNew).toBe(false);
|
|
47
54
|
});
|
|
48
55
|
(0, globals_1.it)('when requestSessionRecordQuery has been passed as webclient property but no such session exists in db', async () => {
|
|
@@ -54,10 +61,9 @@ const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
|
54
61
|
const requestSessionRecordQuery = globals_1.jest.fn();
|
|
55
62
|
const props = {
|
|
56
63
|
requestSessionRecordQuery,
|
|
57
|
-
sessionTokenSecret: 'some-secret',
|
|
58
64
|
};
|
|
59
65
|
requestSessionRecordQuery.mockReturnValueOnce(Promise.resolve({ 'sessionInfo.user.id': 'hans@apptiva.ch' }));
|
|
60
|
-
const { isNew } = await (0, requestSessionData_1.default)('session-id', querystrings, sessionsCollection, 'test-bot', props);
|
|
66
|
+
const { sessionId, isNew } = await (0, requestSessionData_1.default)('session-id', querystrings, sessionsCollection, 'test-bot', props);
|
|
61
67
|
(0, globals_1.expect)(requestSessionRecordQuery).toHaveBeenCalledTimes(1);
|
|
62
68
|
(0, globals_1.expect)(requestSessionRecordQuery).toHaveBeenCalledWith({
|
|
63
69
|
querystrings,
|
|
@@ -69,6 +75,7 @@ const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
|
69
75
|
'sessionInfo.client.type': 'webclient',
|
|
70
76
|
'sessionInfo.user.id': 'hans@apptiva.ch',
|
|
71
77
|
}, { _id: 1, sessionInfo: 1 });
|
|
78
|
+
(0, globals_1.expect)(sessionId).toBe('some-uuid');
|
|
72
79
|
(0, globals_1.expect)(isNew).toBe(true);
|
|
73
80
|
});
|
|
74
81
|
(0, globals_1.it)('when requestSessionRecordQuery has been passed as webclient property and session exists in db', async () => {
|
|
@@ -80,10 +87,9 @@ const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
|
80
87
|
const requestSessionRecordQuery = globals_1.jest.fn();
|
|
81
88
|
const props = {
|
|
82
89
|
requestSessionRecordQuery,
|
|
83
|
-
sessionTokenSecret: 'some-secret',
|
|
84
90
|
};
|
|
85
91
|
requestSessionRecordQuery.mockReturnValueOnce(Promise.resolve({ 'sessionInfo.user.id': 'hans@apptiva.ch' }));
|
|
86
|
-
const { isNew } = await (0, requestSessionData_1.default)('session-id', querystrings, sessionsCollection, 'test-bot', props);
|
|
92
|
+
const { sessionId, isNew } = await (0, requestSessionData_1.default)('session-id', querystrings, sessionsCollection, 'test-bot', props);
|
|
87
93
|
(0, globals_1.expect)(requestSessionRecordQuery).toHaveBeenCalledTimes(1);
|
|
88
94
|
(0, globals_1.expect)(requestSessionRecordQuery).toHaveBeenCalledWith({
|
|
89
95
|
querystrings,
|
|
@@ -95,6 +101,7 @@ const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
|
95
101
|
'sessionInfo.client.type': 'webclient',
|
|
96
102
|
'sessionInfo.user.id': 'hans@apptiva.ch',
|
|
97
103
|
}, { _id: 1, sessionInfo: 1 });
|
|
104
|
+
(0, globals_1.expect)(sessionId).toBe('session-id');
|
|
98
105
|
(0, globals_1.expect)(isNew).toBe(false);
|
|
99
106
|
});
|
|
100
107
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botfabrik/engine-webclient",
|
|
3
|
-
"version": "4.93.
|
|
3
|
+
"version": "4.93.4",
|
|
4
4
|
"description": "Webclient for Botfabriks Bot Engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -25,13 +25,11 @@
|
|
|
25
25
|
"@botfabrik/engine-utils": "^4.90.6",
|
|
26
26
|
"@google-cloud/speech": "^7.1.0",
|
|
27
27
|
"accept-language-parser": "^1.5.0",
|
|
28
|
-
"cookie-parser": "^1.4.7",
|
|
29
28
|
"express": "^5.1.0",
|
|
30
29
|
"uuid": "^11.1.0"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
32
|
"@types/accept-language-parser": "^1.5.8",
|
|
34
|
-
"@types/cookie-parser": "^1.4.9",
|
|
35
33
|
"@types/express": "^5.0.3",
|
|
36
34
|
"@types/serve-static": "^1.15.8",
|
|
37
35
|
"@types/ua-parser-js": "^0.7.39",
|
|
@@ -41,5 +39,5 @@
|
|
|
41
39
|
"tsx": "^4.20.1",
|
|
42
40
|
"typescript": "5.8.3"
|
|
43
41
|
},
|
|
44
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "55a358c8f29b658cb1579f66d88cbdcef4561b36"
|
|
45
43
|
}
|