@botfabrik/engine-webclient 4.121.7 → 4.122.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/README.md +13 -4
- package/dist/createSessionInfo.js +25 -10
- package/dist/createSessionInfo.test.js +3 -2
- package/dist/types.d.ts +26 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -135,18 +135,27 @@ Beispiel
|
|
|
135
135
|
|
|
136
136
|
Eine Liste von projektspezifischen Einträgen, die im Chat-Menü angezeigt werden sollen.
|
|
137
137
|
|
|
138
|
-
###
|
|
138
|
+
### enrichUserInfo (optional)
|
|
139
139
|
|
|
140
140
|
Diese Funktion wird beim Erzeugen eines neuen Session Records aufgerufen. Man hat damit die Möglichkeit, die Session Daten unter `session.getSessionInfo().user` projektspezifisch anzupassen.
|
|
141
141
|
|
|
142
|
-
Die Funktion erhält als Parameter
|
|
142
|
+
Die Funktion erhält als Parameter ein Objekt mit folgenden Eigenschaften:
|
|
143
|
+
|
|
144
|
+
- `user` – Das aktuelle Session-User-Objekt, aufgebaut aus Authentifizierung und Query-Parametern.
|
|
145
|
+
- `querystrings` – Die geparsten Query-Parameter der Client-URL.
|
|
146
|
+
- `headers` – Die eingehenden HTTP-Request-Header.
|
|
147
|
+
- `ip` – Die IP-Adresse des Clients (oder `undefined`).
|
|
148
|
+
|
|
149
|
+
Als Resultat wird ein partielles User-Info-Objekt erwartet. Dessen Eigenschaften werden in die bestehenden User-Daten eingemergt.
|
|
143
150
|
|
|
144
151
|
Beispiel:
|
|
145
152
|
|
|
146
153
|
```typescript
|
|
147
|
-
|
|
154
|
+
const enrichUserInfo: EnrichUserInfo = async ({ querystrings }) => {
|
|
148
155
|
const accessToken = querystrings.accessToken;
|
|
149
|
-
const userProfile: UserProfile = await fetchUserProfile(
|
|
156
|
+
const userProfile: UserProfile = await fetchUserProfile(
|
|
157
|
+
accessToken as string
|
|
158
|
+
);
|
|
150
159
|
|
|
151
160
|
return {
|
|
152
161
|
id: userProfile.username + '@' + userProfile.domain,
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { CLIENT_TYPE } from './constants.js';
|
|
2
|
-
const
|
|
2
|
+
const createSessionInfo = (socket, clientName, environment, sessionInfo, userId, locale, querystrings, authenticatedUser, props) => async () => {
|
|
3
|
+
const headers = socket.request.headers;
|
|
4
|
+
const ip = extractIpFromSocket(socket);
|
|
3
5
|
const client = {
|
|
4
6
|
...sessionInfo.client,
|
|
5
7
|
name: clientName,
|
|
6
8
|
type: CLIENT_TYPE,
|
|
7
9
|
payload: {
|
|
8
10
|
...sessionInfo.client.payload,
|
|
9
|
-
referrer: decodeURIComponent(querystrings['referrer'] ||
|
|
11
|
+
referrer: decodeURIComponent(querystrings['referrer'] ||
|
|
12
|
+
headers['referer'] ||
|
|
13
|
+
'unknown'),
|
|
10
14
|
querystrings,
|
|
11
15
|
},
|
|
12
16
|
};
|
|
@@ -29,17 +33,17 @@ const createSessionInfoBase = async (userId, querystrings, headers, clientName,
|
|
|
29
33
|
locale,
|
|
30
34
|
};
|
|
31
35
|
const contexts = sessionInfo.contexts;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
if (props.enrichUserInfo) {
|
|
37
|
+
const userInfos = await props.enrichUserInfo({
|
|
38
|
+
user,
|
|
39
|
+
querystrings,
|
|
40
|
+
headers,
|
|
41
|
+
ip,
|
|
42
|
+
});
|
|
43
|
+
user = { ...user, ...userInfos };
|
|
36
44
|
}
|
|
37
45
|
return { client, user, contexts, environment };
|
|
38
46
|
};
|
|
39
|
-
const createSessionInfo = (socket, clientName, environment, sessionInfo, userId, locale, querystrings, authenticatedUser, props) => async () => {
|
|
40
|
-
const request = socket.request;
|
|
41
|
-
return await createSessionInfoBase(userId, querystrings, request.headers, clientName, environment, sessionInfo, locale, authenticatedUser, props);
|
|
42
|
-
};
|
|
43
47
|
const guestNamesFromEMail = (email) => {
|
|
44
48
|
try {
|
|
45
49
|
const namePart = email?.split('@')[0];
|
|
@@ -61,4 +65,15 @@ const capitalize = (s) => {
|
|
|
61
65
|
return '';
|
|
62
66
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
63
67
|
};
|
|
68
|
+
const extractIpFromSocket = (socket) => {
|
|
69
|
+
const headers = socket.handshake.headers;
|
|
70
|
+
const forwarded = headers['x-forwarded-for'];
|
|
71
|
+
if (typeof forwarded === 'string') {
|
|
72
|
+
return forwarded.split(',')[0]?.trim();
|
|
73
|
+
}
|
|
74
|
+
if (Array.isArray(forwarded) && forwarded.length > 0) {
|
|
75
|
+
return forwarded[0];
|
|
76
|
+
}
|
|
77
|
+
return socket.handshake.address;
|
|
78
|
+
};
|
|
64
79
|
export default createSessionInfo;
|
|
@@ -22,6 +22,7 @@ describe('create session info', () => {
|
|
|
22
22
|
},
|
|
23
23
|
handshake: {
|
|
24
24
|
query: querystrings,
|
|
25
|
+
headers,
|
|
25
26
|
},
|
|
26
27
|
};
|
|
27
28
|
const webClientProps = {
|
|
@@ -54,7 +55,7 @@ describe('create session info', () => {
|
|
|
54
55
|
expect(sessionInfo.user.payload).toStrictEqual({});
|
|
55
56
|
});
|
|
56
57
|
it('with enhanced user data', async () => {
|
|
57
|
-
const
|
|
58
|
+
const enrichUserInfo = async () => {
|
|
58
59
|
const userProfile = {
|
|
59
60
|
username: 'hans.muster',
|
|
60
61
|
domain: 'PRIMARY',
|
|
@@ -69,7 +70,7 @@ describe('create session info', () => {
|
|
|
69
70
|
};
|
|
70
71
|
const props = {
|
|
71
72
|
...webClientProps,
|
|
72
|
-
|
|
73
|
+
enrichUserInfo,
|
|
73
74
|
};
|
|
74
75
|
const sessionInfo = await createSessionInfo(socket, 'my-client', 'TEST', defaultSessionInfo, 'my-user-id', 'de_DE', {}, undefined, props)();
|
|
75
76
|
expect(sessionInfo.user.id).toBe('hans.muster@PRIMARY');
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Action, SessionInfoUser } from '@botfabrik/engine-domain';
|
|
2
|
+
import { IncomingHttpHeaders } from 'node:http';
|
|
3
|
+
import { ParsedUrlQuery } from 'node:querystring';
|
|
2
4
|
export type SessionInfoClientPayload = {
|
|
3
5
|
querystrings: any;
|
|
4
6
|
referrer: string;
|
|
@@ -10,9 +12,26 @@ export type ConversationRating = {
|
|
|
10
12
|
};
|
|
11
13
|
export type SessionInfoUserPayload = object;
|
|
12
14
|
export type WebclientMiddlewareState = object;
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Callback to enrich the user's session info with additional data from an external source.
|
|
17
|
+
*
|
|
18
|
+
* Called during session initialization with the current user, query strings, and HTTP headers.
|
|
19
|
+
* The returned partial object is merged into the existing user info.
|
|
20
|
+
*
|
|
21
|
+
* @param props.user - The current session user object built from authentication and query parameters.
|
|
22
|
+
* @param props.querystrings - The parsed query string parameters from the client URL.
|
|
23
|
+
* @param props.headers - The incoming HTTP request headers.
|
|
24
|
+
* @param props.ip - The client's IP address, extracted from the socket connection.
|
|
25
|
+
* @returns A promise resolving to a partial user info object whose properties will be merged into the session user.
|
|
26
|
+
*/
|
|
27
|
+
export type EnrichUserInfo = (props: {
|
|
28
|
+
user: SessionInfoUser<SessionInfoUserPayload>;
|
|
29
|
+
querystrings: ParsedUrlQuery;
|
|
30
|
+
headers: IncomingHttpHeaders;
|
|
31
|
+
ip: string | undefined;
|
|
32
|
+
}) => Promise<Partial<SessionInfoUser<SessionInfoUserPayload>>>;
|
|
14
33
|
export type RequestSessionRecordQuery = (params: {
|
|
15
|
-
querystrings:
|
|
34
|
+
querystrings: ParsedUrlQuery;
|
|
16
35
|
sessionId: string;
|
|
17
36
|
}) => Promise<Record<string, unknown>>;
|
|
18
37
|
export type MenuItemType = 'link' | 'action';
|
|
@@ -87,7 +106,11 @@ export type Auth = {
|
|
|
87
106
|
};
|
|
88
107
|
export interface WebClientProps {
|
|
89
108
|
getStartedAction?: Action;
|
|
90
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Optional callback to enrich the user's session info with additional data.
|
|
111
|
+
* See {@link EnrichUserInfo} for details.
|
|
112
|
+
*/
|
|
113
|
+
enrichUserInfo?: EnrichUserInfo;
|
|
91
114
|
requestSessionRecordQuery?: RequestSessionRecordQuery;
|
|
92
115
|
speech?: SpeechToTextProps | undefined;
|
|
93
116
|
expandChatWindowAtStart?: Devices;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botfabrik/engine-webclient",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.122.0",
|
|
4
4
|
"description": "Webclient for Botfabriks Bot Engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"tsx": "^4.22.3",
|
|
56
56
|
"typescript": "6.0.3"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "a44d1eec77571e783f80f244474873f286a3e83b"
|
|
59
59
|
}
|