@burgan-tech/morph-touch-runtime 0.0.6 → 0.0.8

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.
Files changed (60) hide show
  1. package/burgan-tech-morph-touch-runtime-0.0.8.tgz +0 -0
  2. package/morph-touch/Functions/get-absence-entry.1.0.0.json +1 -1
  3. package/morph-touch/Functions/get-advisor-stats.1.0.0.json +1 -1
  4. package/morph-touch/Functions/get-available-slots.1.0.0.json +1 -1
  5. package/morph-touch/Functions/get-rezervations.1.0.0.json +1 -1
  6. package/morph-touch/Functions/src/GetAbsenceEntryMapping.csx +18 -4
  7. package/morph-touch/Functions/src/GetAdvisorStatsMapping.csx +22 -8
  8. package/morph-touch/Functions/src/GetAvailableSlotsMapping.csx +22 -14
  9. package/morph-touch/Functions/src/GetRezervationsMapping.csx +46 -9
  10. package/morph-touch/Functions/src/SendCancelNotificationMapping.csx +27 -2
  11. package/morph-touch/Tasks/login-for-chat.1.0.0.json +27 -0
  12. package/morph-touch/Tasks/register-for-chat.1.0.0.json +27 -0
  13. package/morph-touch/Workflows/chat-room.json +273 -14
  14. package/morph-touch/Workflows/notification-sender.json +2 -2
  15. package/morph-touch/Workflows/rezervation-start.json +39 -2
  16. package/morph-touch/Workflows/rezervation-transfer.json +44 -7
  17. package/morph-touch/Workflows/rezervation-update.json +4 -4
  18. package/morph-touch/Workflows/rezervation.json +135 -45
  19. package/morph-touch/Workflows/src/CanStartRezervationTimerMapping.csx +18 -3
  20. package/morph-touch/Workflows/src/ChatRoomRemoveMapping.csx +10 -1
  21. package/morph-touch/Workflows/src/ChatRoomTransferInviteMapping.csx +10 -1
  22. package/morph-touch/Workflows/src/ChatRoomTransferRemoveMapping.csx +9 -1
  23. package/morph-touch/Workflows/src/ChatRoomUpdateMapping.csx +10 -1
  24. package/morph-touch/Workflows/src/CheckDuplicateRezervationMapping.csx +17 -3
  25. package/morph-touch/Workflows/src/CheckRandevuTimeMapping.csx +16 -2
  26. package/morph-touch/Workflows/src/CreateChatRoomForRezervationMapping.csx +12 -2
  27. package/morph-touch/Workflows/src/CreatePermanentChatRoomMapping.csx +11 -1
  28. package/morph-touch/Workflows/src/EnrichRezervationsForTransferMapping.csx +18 -4
  29. package/morph-touch/Workflows/src/FetchRoomMessagesForSummaryMapping.csx +10 -2
  30. package/morph-touch/Workflows/src/InviteAdvisorForRandevuUpdateMapping.csx +10 -1
  31. package/morph-touch/Workflows/src/InviteNewAdvisorToRezervationRoomMapping.csx +11 -2
  32. package/morph-touch/Workflows/src/InviteNewParticipantToRandevuRoomMapping.csx +10 -1
  33. package/morph-touch/Workflows/src/JoinChatRoomForAddParticipantMapping.csx +5 -1
  34. package/morph-touch/Workflows/src/JoinChatRoomForRandevuStartMapping.csx +5 -1
  35. package/morph-touch/Workflows/src/JoinChatRoomForRezervationMapping.csx +4 -0
  36. package/morph-touch/Workflows/src/JoinMatrixRoomMapping.csx +11 -1
  37. package/morph-touch/Workflows/src/JoinUserToRoomMapping.csx +6 -0
  38. package/morph-touch/Workflows/src/LoginForAddParticipantChatMapping.csx +35 -6
  39. package/morph-touch/Workflows/src/LoginForChatRoomMapping.csx +121 -0
  40. package/morph-touch/Workflows/src/LoginForJoinUserToRoomMapping.csx +142 -0
  41. package/morph-touch/Workflows/src/LoginForRandevuStartChatMapping.csx +35 -10
  42. package/morph-touch/Workflows/src/LoginForTransferChatMapping.csx +153 -0
  43. package/morph-touch/Workflows/src/RegisterForAddParticipantChatMapping.csx +74 -0
  44. package/morph-touch/Workflows/src/RegisterForChatRoomMapping.csx +74 -0
  45. package/morph-touch/Workflows/src/RegisterForJoinUserToRoomMapping.csx +87 -0
  46. package/morph-touch/Workflows/src/RegisterForRandevuStartChatMapping.csx +80 -0
  47. package/morph-touch/Workflows/src/RegisterForTransferChatMapping.csx +113 -0
  48. package/morph-touch/Workflows/src/SendPushNotificationMapping.csx +25 -4
  49. package/morph-touch/Workflows/src/SendSmsNotificationMapping.csx +25 -4
  50. package/morph-touch/Workflows/src/SendSummaryToNewRoomMapping.csx +10 -2
  51. package/morph-touch/Workflows/src/SetRoomHistoryVisibilityMapping.csx +12 -4
  52. package/morph-touch/Workflows/src/ValidateDateForRezervationMapping.csx +16 -2
  53. package/morph-touch/Workflows/src/ValidateSlotForRandevuUpdateMapping.csx +22 -15
  54. package/morph-touch/Workflows/src/ValidateSlotForRezervationMapping.csx +23 -16
  55. package/morph-touch/Workflows/src/ValidateTransferMapping.csx +16 -2
  56. package/morph-touch/doc/morph-touch-domain.en.md +420 -6
  57. package/morph-touch/doc/morph-touch-domain.md +423 -6
  58. package/package.json +1 -1
  59. package/vnext.config.json +1 -1
  60. package/burgan-tech-morph-touch-runtime-0.0.6.tgz +0 -0
@@ -84,7 +84,7 @@ public class CheckDuplicateRezervationMapping : ScriptBase, IMapping
84
84
  if (!string.IsNullOrEmpty(newStartStr) && !string.IsNullOrEmpty(newEndStr))
85
85
  {
86
86
  DateTime newStart = default, newEnd = default;
87
- if (DateTime.TryParse(newStartStr, out newStart) && DateTime.TryParse(newEndStr, out newEnd))
87
+ if (TryParseToUtc(newStartStr, out newStart) && TryParseToUtc(newEndStr, out newEnd))
88
88
  {
89
89
  foreach (var item in items)
90
90
  {
@@ -97,8 +97,8 @@ public class CheckDuplicateRezervationMapping : ScriptBase, IMapping
97
97
  continue;
98
98
 
99
99
  DateTime existingStart = default, existingEnd = default;
100
- if (!DateTime.TryParse(existingStartStr, out existingStart) ||
101
- !DateTime.TryParse(existingEndStr, out existingEnd))
100
+ if (!TryParseToUtc(existingStartStr, out existingStart) ||
101
+ !TryParseToUtc(existingEndStr, out existingEnd))
102
102
  continue;
103
103
 
104
104
  if (existingStart < newEnd && existingEnd > newStart)
@@ -114,6 +114,20 @@ public class CheckDuplicateRezervationMapping : ScriptBase, IMapping
114
114
  return Task.FromResult(new ScriptResponse());
115
115
  }
116
116
 
117
+ private bool TryParseToUtc(string dateStr, out DateTime utcDateTime)
118
+ {
119
+ utcDateTime = default;
120
+ if (string.IsNullOrEmpty(dateStr)) return false;
121
+ if (DateTimeOffset.TryParse(dateStr,
122
+ System.Globalization.CultureInfo.InvariantCulture,
123
+ System.Globalization.DateTimeStyles.None, out var dto))
124
+ {
125
+ utcDateTime = dto.UtcDateTime;
126
+ return true;
127
+ }
128
+ return false;
129
+ }
130
+
117
131
  private string GetString(dynamic obj, string name)
118
132
  {
119
133
  if (obj == null) return null;
@@ -32,10 +32,10 @@ public class CheckRandevuTimeMapping : ScriptBase, IMapping
32
32
  throw new InvalidOperationException("MEET_NOT_STARTED: startDateTime is required");
33
33
 
34
34
  DateTime startDateTime;
35
- if (!DateTime.TryParse(startDateTimeStr, out startDateTime))
35
+ if (!TryParseToUtc(startDateTimeStr, out startDateTime))
36
36
  throw new InvalidOperationException("MEET_NOT_STARTED: Invalid startDateTime format");
37
37
 
38
- var now = DateTime.UtcNow.AddHours(3);
38
+ var now = DateTime.UtcNow;
39
39
  var diff = startDateTime - now;
40
40
 
41
41
  if (diff.TotalMinutes > MaxMinutesBeforeStart)
@@ -50,6 +50,20 @@ public class CheckRandevuTimeMapping : ScriptBase, IMapping
50
50
  return Task.FromResult(new ScriptResponse { Data = result });
51
51
  }
52
52
 
53
+ private bool TryParseToUtc(string dateStr, out DateTime utcDateTime)
54
+ {
55
+ utcDateTime = default;
56
+ if (string.IsNullOrEmpty(dateStr)) return false;
57
+ if (DateTimeOffset.TryParse(dateStr,
58
+ System.Globalization.CultureInfo.InvariantCulture,
59
+ System.Globalization.DateTimeStyles.None, out var dto))
60
+ {
61
+ utcDateTime = dto.UtcDateTime;
62
+ return true;
63
+ }
64
+ return false;
65
+ }
66
+
53
67
  private string GetString(dynamic obj, string name)
54
68
  {
55
69
  if (obj == null) return null;
@@ -25,6 +25,11 @@ public class CreateChatRoomForRezervationMapping : ScriptBase, IMapping
25
25
  var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
26
26
  if (string.IsNullOrWhiteSpace(matrixBaseUrl))
27
27
  throw new InvalidOperationException("MatrixBaseUrl secret is required");
28
+
29
+ var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
30
+ if (string.IsNullOrWhiteSpace(SynapseServer))
31
+ throw new InvalidOperationException("SynapseServer secret is required");
32
+
28
33
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/createRoom";
29
34
  httpTask.SetUrl(fullUrl);
30
35
 
@@ -40,15 +45,20 @@ public class CreateChatRoomForRezervationMapping : ScriptBase, IMapping
40
45
 
41
46
  var inviteList = new List<string>();
42
47
  if (!string.IsNullOrWhiteSpace(advisorId))
43
- inviteList.Add(advisorId.StartsWith("@") ? advisorId : $"@{advisorId}:localhost");
48
+ inviteList.Add(advisorId.StartsWith("@") ? advisorId : $"@{advisorId}:{SynapseServer}");
49
+
50
+ var chatIntegration = data?.chatIntegration;
51
+ var sessionId = chatIntegration != null ? GetString(chatIntegration, "sessionId") : null;
44
52
 
45
53
  var headers = new Dictionary<string, string>
46
54
  {
47
55
  ["Content-Type"] = "application/json",
48
56
  ["Accept"] = "application/json",
49
57
  ["X-Matrix-User"] = user,
50
- ["x-matrix-user"] = user
58
+ ["x-matrix-user"] = user
51
59
  };
60
+ if (!string.IsNullOrWhiteSpace(sessionId))
61
+ headers["Authorization"] = "Bearer " + sessionId;
52
62
  httpTask.SetHeaders(headers);
53
63
 
54
64
  var body = new
@@ -30,6 +30,11 @@ public class CreatePermanentChatRoomMapping : ScriptBase, IMapping
30
30
  var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
31
31
  if (string.IsNullOrWhiteSpace(matrixBaseUrl))
32
32
  throw new InvalidOperationException("MatrixBaseUrl secret is required");
33
+
34
+ var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
35
+ if (string.IsNullOrWhiteSpace(SynapseServer))
36
+ throw new InvalidOperationException("SynapseServer secret is required");
37
+
33
38
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/createRoom";
34
39
  httpTask.SetUrl(fullUrl);
35
40
 
@@ -53,7 +58,10 @@ public class CreatePermanentChatRoomMapping : ScriptBase, IMapping
53
58
 
54
59
  var inviteList = new List<string>();
55
60
  if (!string.IsNullOrWhiteSpace(advisorId))
56
- inviteList.Add(advisorId.StartsWith("@") ? advisorId : $"@{advisorId}:localhost");
61
+ inviteList.Add(advisorId.StartsWith("@") ? advisorId : $"@{advisorId}:{SynapseServer}");
62
+
63
+ var chatIntegration = data?.chatIntegration;
64
+ var sessionId = GetString(chatIntegration, "sessionId");
57
65
 
58
66
  var headers = new Dictionary<string, string>
59
67
  {
@@ -61,6 +69,8 @@ public class CreatePermanentChatRoomMapping : ScriptBase, IMapping
61
69
  ["Accept"] = "application/json",
62
70
  ["X-Matrix-User"] = user
63
71
  };
72
+ if (!string.IsNullOrWhiteSpace(sessionId))
73
+ headers["Authorization"] = "Bearer " + sessionId;
64
74
  httpTask.SetHeaders(headers);
65
75
 
66
76
  var body = new
@@ -148,7 +148,7 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
148
148
  DateTime rezStart = DateTime.MinValue;
149
149
  DateTime rezEnd = DateTime.MinValue;
150
150
  if (!string.IsNullOrEmpty(rezStartStr) && !string.IsNullOrEmpty(rezEndStr) &&
151
- DateTime.TryParse(rezStartStr, out rezStart) && DateTime.TryParse(rezEndStr, out rezEnd) &&
151
+ TryParseToUtc(rezStartStr, out rezStart) && TryParseToUtc(rezEndStr, out rezEnd) &&
152
152
  allItems != null)
153
153
  {
154
154
  foreach (var item in allItems)
@@ -166,7 +166,7 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
166
166
 
167
167
  DateTime itemStart = DateTime.MinValue;
168
168
  DateTime itemEnd = DateTime.MinValue;
169
- if (DateTime.TryParse(itemStartStr, out itemStart) && DateTime.TryParse(itemEndStr, out itemEnd))
169
+ if (TryParseToUtc(itemStartStr, out itemStart) && TryParseToUtc(itemEndStr, out itemEnd))
170
170
  {
171
171
  if (itemStart < rezEnd && itemEnd > rezStart)
172
172
  {
@@ -351,7 +351,7 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
351
351
 
352
352
  DateTime startDateTime = DateTime.MinValue;
353
353
  DateTime endDateTime = DateTime.MinValue;
354
- if (!DateTime.TryParse(startDateTimeStr, out startDateTime) || !DateTime.TryParse(endDateTimeStr, out endDateTime))
354
+ if (!TryParseToUtc(startDateTimeStr, out startDateTime) || !TryParseToUtc(endDateTimeStr, out endDateTime))
355
355
  continue;
356
356
 
357
357
  if (date.Date < startDateTime.Date || date.Date > endDateTime.Date)
@@ -442,7 +442,7 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
442
442
 
443
443
  DateTime startDateTime = DateTime.MinValue;
444
444
  DateTime endDateTime = DateTime.MinValue;
445
- if (!DateTime.TryParse(startDateTimeStr, out startDateTime) || !DateTime.TryParse(endDateTimeStr, out endDateTime))
445
+ if (!TryParseToUtc(startDateTimeStr, out startDateTime) || !TryParseToUtc(endDateTimeStr, out endDateTime))
446
446
  continue;
447
447
 
448
448
  if (date.Date < startDateTime.Date || date.Date > endDateTime.Date)
@@ -470,6 +470,20 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
470
470
 
471
471
  #region Helpers
472
472
 
473
+ private bool TryParseToUtc(string dateStr, out DateTime utcDateTime)
474
+ {
475
+ utcDateTime = default;
476
+ if (string.IsNullOrEmpty(dateStr)) return false;
477
+ if (DateTimeOffset.TryParse(dateStr,
478
+ System.Globalization.CultureInfo.InvariantCulture,
479
+ System.Globalization.DateTimeStyles.None, out var dto))
480
+ {
481
+ utcDateTime = dto.UtcDateTime;
482
+ return true;
483
+ }
484
+ return false;
485
+ }
486
+
473
487
  private string GetString(dynamic obj, string name)
474
488
  {
475
489
  if (obj == null) return null;
@@ -64,11 +64,19 @@ public class FetchRoomMessagesForSummaryMapping : ScriptBase, IMapping
64
64
  "/messages?dir=b&limit=100";
65
65
 
66
66
  httpTask.SetUrl(fullUrl);
67
- httpTask.SetHeaders(new Dictionary<string, string>
67
+
68
+ string sessionId = null;
69
+ if (HasProperty(data, "chatIntegration") && data.chatIntegration != null)
70
+ sessionId = GetString(data.chatIntegration, "sessionId");
71
+
72
+ var headers = new Dictionary<string, string>
68
73
  {
69
74
  ["Accept"] = "application/json",
70
75
  ["X-Matrix-User"] = user
71
- });
76
+ };
77
+ if (!string.IsNullOrWhiteSpace(sessionId))
78
+ headers["Authorization"] = "Bearer " + sessionId;
79
+ httpTask.SetHeaders(headers);
72
80
 
73
81
  return new ScriptResponse();
74
82
  }
@@ -40,17 +40,26 @@ public class InviteAdvisorForRandevuUpdateMapping : ScriptBase, IMapping
40
40
  var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
41
41
  if (string.IsNullOrWhiteSpace(matrixBaseUrl))
42
42
  throw new InvalidOperationException("MatrixBaseUrl secret is required");
43
+
44
+ var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
45
+ if (string.IsNullOrWhiteSpace(SynapseServer))
46
+ throw new InvalidOperationException("SynapseServer secret is required");
47
+
43
48
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId ?? "") + "/invite";
44
49
  httpTask.SetUrl(fullUrl);
45
50
 
51
+ var sessionId = GetString(chatIntegration, "sessionId");
52
+
46
53
  var headers = new Dictionary<string, string>
47
54
  {
48
55
  ["Content-Type"] = "application/json",
49
56
  ["Accept"] = "application/json",
50
57
  ["x-matrix-user"] = user.Trim()
51
58
  };
59
+ if (!string.IsNullOrWhiteSpace(sessionId))
60
+ headers["Authorization"] = "Bearer " + sessionId;
52
61
  httpTask.SetHeaders(headers);
53
- var userId = (advisor?.Trim() ?? "").StartsWith("@") ? advisor.Trim() : $"@{advisor?.Trim()}:localhost";
62
+ var userId = (advisor?.Trim() ?? "").StartsWith("@") ? advisor.Trim() : $"@{advisor?.Trim()}:{SynapseServer}";
54
63
  httpTask.SetBody(new { user_id = userId });
55
64
 
56
65
  return new ScriptResponse();
@@ -8,7 +8,7 @@ using BBT.Workflow.Definitions;
8
8
  /// Mapping for invite-user-to-rezervation-room HttpTask (Type 6).
9
9
  /// Invites new advisor to existing Matrix room via native /_matrix/client/v3/rooms/{roomId}/invite.
10
10
  /// APISIX converts X-Matrix-User header to Bearer token automatically.
11
- /// Formats target user ID as @{user}:localhost per Matrix spec.
11
+ /// Formats target user ID as @{user}:{SynapseServer} per Matrix spec.
12
12
  /// </summary>
13
13
  public class InviteNewAdvisorToRezervationRoomMapping : ScriptBase, IMapping
14
14
  {
@@ -42,10 +42,17 @@ public class InviteNewAdvisorToRezervationRoomMapping : ScriptBase, IMapping
42
42
  var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
43
43
  if (string.IsNullOrWhiteSpace(matrixBaseUrl))
44
44
  throw new InvalidOperationException("MatrixBaseUrl secret is required");
45
+
46
+ var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
47
+ if (string.IsNullOrWhiteSpace(SynapseServer))
48
+ throw new InvalidOperationException("SynapseServer secret is required");
49
+
45
50
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId) + "/invite";
46
51
  httpTask.SetUrl(fullUrl);
47
52
 
48
- var matrixUserId = advisor.Trim().StartsWith("@") ? advisor.Trim() : $"@{advisor.Trim()}:localhost";
53
+ var matrixUserId = advisor.Trim().StartsWith("@") ? advisor.Trim() : $"@{advisor.Trim()}:{SynapseServer}";
54
+
55
+ var sessionId = GetString(chatIntegration, "sessionId");
49
56
 
50
57
  var headers = new Dictionary<string, string>
51
58
  {
@@ -53,6 +60,8 @@ public class InviteNewAdvisorToRezervationRoomMapping : ScriptBase, IMapping
53
60
  ["Accept"] = "application/json",
54
61
  ["X-Matrix-User"] = user
55
62
  };
63
+ if (!string.IsNullOrWhiteSpace(sessionId))
64
+ headers["Authorization"] = "Bearer " + sessionId;
56
65
  httpTask.SetHeaders(headers);
57
66
 
58
67
  httpTask.SetBody(new { user_id = matrixUserId });
@@ -38,9 +38,16 @@ public class InviteNewParticipantToRandevuRoomMapping : ScriptBase, IMapping
38
38
  var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
39
39
  if (string.IsNullOrWhiteSpace(matrixBaseUrl))
40
40
  throw new InvalidOperationException("MatrixBaseUrl secret is required");
41
+
42
+ var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
43
+ if (string.IsNullOrWhiteSpace(SynapseServer))
44
+ throw new InvalidOperationException("SynapseServer secret is required");
45
+
41
46
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId ?? "") + "/invite";
42
47
  httpTask.SetUrl(fullUrl);
43
48
 
49
+ var sessionId = GetString(chatIntegration, "sessionId");
50
+
44
51
  var headers = new Dictionary<string, string>
45
52
  {
46
53
  ["Content-Type"] = "application/json",
@@ -48,9 +55,11 @@ public class InviteNewParticipantToRandevuRoomMapping : ScriptBase, IMapping
48
55
  };
49
56
  if (!string.IsNullOrWhiteSpace(inviter))
50
57
  headers["x-matrix-user"] = inviter.Trim();
58
+ if (!string.IsNullOrWhiteSpace(sessionId))
59
+ headers["Authorization"] = "Bearer " + sessionId;
51
60
 
52
61
  httpTask.SetHeaders(headers);
53
- var userId = newUserId.Trim().StartsWith("@") ? newUserId.Trim() : $"@{newUserId.Trim()}:localhost";
62
+ var userId = newUserId.Trim().StartsWith("@") ? newUserId.Trim() : $"@{newUserId.Trim()}:{SynapseServer}";
54
63
  httpTask.SetBody(new { user_id = userId });
55
64
 
56
65
  return new ScriptResponse();
@@ -6,7 +6,7 @@ using BBT.Workflow.Definitions;
6
6
 
7
7
  /// <summary>
8
8
  /// Mapping for join-chat-room-for-rezervation when used in add-participant-to-rezervation flow.
9
- /// Uses x-matrix-user = newUserId (the invited participant joining). No login/sessionId.
9
+ /// Uses x-matrix-user = newUserId (the invited participant joining). Uses sessionId from preceding login task.
10
10
  /// </summary>
11
11
  public class JoinChatRoomForAddParticipantMapping : ScriptBase, IMapping
12
12
  {
@@ -37,12 +37,16 @@ public class JoinChatRoomForAddParticipantMapping : ScriptBase, IMapping
37
37
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/join/" + Uri.EscapeDataString(roomId ?? "");
38
38
  httpTask.SetUrl(fullUrl);
39
39
 
40
+ var sessionId = GetString(chatIntegration, "sessionId");
41
+
40
42
  var headers = new Dictionary<string, string>
41
43
  {
42
44
  ["Content-Type"] = "application/json",
43
45
  ["Accept"] = "application/json",
44
46
  ["x-matrix-user"] = newUserId.Trim()
45
47
  };
48
+ if (!string.IsNullOrWhiteSpace(sessionId))
49
+ headers["Authorization"] = "Bearer " + sessionId;
46
50
 
47
51
  httpTask.SetHeaders(headers);
48
52
  httpTask.SetBody(new { });
@@ -6,7 +6,7 @@ using BBT.Workflow.Definitions;
6
6
 
7
7
  /// <summary>
8
8
  /// Mapping for join-chat-room-for-rezervation when used in rezervation-start flow.
9
- /// Uses chatIntegration.roomId from rezervation. Uses x-matrix-user header instead of login/sessionId.
9
+ /// Uses chatIntegration.roomId and sessionId (from preceding login task) for authentication.
10
10
  /// </summary>
11
11
  public class JoinChatRoomForRandevuStartMapping : ScriptBase, IMapping
12
12
  {
@@ -44,12 +44,16 @@ public class JoinChatRoomForRandevuStartMapping : ScriptBase, IMapping
44
44
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/join/" + Uri.EscapeDataString(roomId ?? "");
45
45
  httpTask.SetUrl(fullUrl);
46
46
 
47
+ var sessionId = GetString(chatIntegration, "sessionId");
48
+
47
49
  var headers = new Dictionary<string, string>
48
50
  {
49
51
  ["Content-Type"] = "application/json",
50
52
  ["Accept"] = "application/json",
51
53
  ["x-matrix-user"] = xMatrixUser.Trim()
52
54
  };
55
+ if (!string.IsNullOrWhiteSpace(sessionId))
56
+ headers["Authorization"] = "Bearer " + sessionId;
53
57
 
54
58
  httpTask.SetHeaders(headers);
55
59
  httpTask.SetBody(new { });
@@ -39,12 +39,16 @@ public class JoinChatRoomForRezervationMapping : ScriptBase, IMapping
39
39
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/join/" + Uri.EscapeDataString(roomId ?? "");
40
40
  httpTask.SetUrl(fullUrl);
41
41
 
42
+ var sessionId = GetString(chatIntegration, "sessionId");
43
+
42
44
  var headers = new Dictionary<string, string>
43
45
  {
44
46
  ["Content-Type"] = "application/json",
45
47
  ["Accept"] = "application/json",
46
48
  ["x-matrix-user"] = xMatrixUser.Trim()
47
49
  };
50
+ if (!string.IsNullOrWhiteSpace(sessionId))
51
+ headers["Authorization"] = "Bearer " + sessionId;
48
52
 
49
53
  httpTask.SetHeaders(headers);
50
54
  httpTask.SetBody(new { });
@@ -27,23 +27,33 @@ public class JoinMatrixRoomMapping : ScriptBase, IMapping
27
27
  if (string.IsNullOrWhiteSpace(matrixBaseUrl))
28
28
  throw new InvalidOperationException("MatrixBaseUrl secret is required");
29
29
 
30
+ var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
31
+ if (string.IsNullOrWhiteSpace(SynapseServer))
32
+ throw new InvalidOperationException("SynapseServer secret is required");
33
+
30
34
  var data = context.Instance?.Data;
31
35
  var user = data?.user?.ToString();
32
36
  var instanceKey = context.Instance?.Key;
33
37
 
34
38
  var prefixedName = $"{user}_{instanceKey}";
35
39
  var aliasName = Regex.Replace(prefixedName.ToLower(), @"[^a-z0-9_]", "-");
36
- var alias = $"#{aliasName}:localhost";
40
+ var alias = $"#{aliasName}:{SynapseServer}";
37
41
  var encodedAlias = Uri.EscapeDataString(alias);
38
42
 
39
43
  var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/join/" + encodedAlias;
40
44
  httpTask.SetUrl(fullUrl);
41
45
 
46
+ string sessionId = null;
47
+ if (data != null && HasProperty(data, "chatIntegration") && data.chatIntegration != null)
48
+ sessionId = GetString(data.chatIntegration, "sessionId");
49
+
42
50
  var headers = new Dictionary<string, string>
43
51
  {
44
52
  ["Content-Type"] = "application/json",
45
53
  ["X-Matrix-User"] = user
46
54
  };
55
+ if (!string.IsNullOrWhiteSpace(sessionId))
56
+ headers["Authorization"] = "Bearer " + sessionId;
47
57
  httpTask.SetHeaders(headers);
48
58
  httpTask.SetBody(new { });
49
59
 
@@ -50,12 +50,18 @@ public class JoinUserToRoomMapping : ScriptBase, IMapping
50
50
  xMatrixUser = colonIdx > 0 ? xMatrixUser.Substring(1, colonIdx - 1) : xMatrixUser.Substring(1);
51
51
  }
52
52
 
53
+ string joinSessionId = null;
54
+ if (HasProperty(data, "chatIntegration") && data.chatIntegration != null)
55
+ joinSessionId = GetString(data.chatIntegration, "joinSessionId");
56
+
53
57
  var headers = new Dictionary<string, string>
54
58
  {
55
59
  ["Content-Type"] = "application/json",
56
60
  ["Accept"] = "application/json",
57
61
  ["X-Matrix-User"] = xMatrixUser
58
62
  };
63
+ if (!string.IsNullOrWhiteSpace(joinSessionId))
64
+ headers["Authorization"] = "Bearer " + joinSessionId;
59
65
  httpTask.SetHeaders(headers);
60
66
 
61
67
  httpTask.SetBody(new { });
@@ -1,15 +1,18 @@
1
1
  using System;
2
+ using System.Collections.Generic;
2
3
  using System.Threading.Tasks;
3
4
  using BBT.Workflow.Scripting;
4
5
  using BBT.Workflow.Definitions;
5
6
 
6
7
  /// <summary>
7
8
  /// Mapping for login-for-rezervation-chat when used in add-participant-to-rezervation flow.
9
+ /// Calls POST /_matrix/client/v3/login on Synapse.
8
10
  /// Logs in as newUserId. Output merges session with existing chatIntegration (preserves roomId).
11
+ /// Stores access_token as sessionId for subsequent Matrix API calls.
9
12
  /// </summary>
10
13
  public class LoginForAddParticipantChatMapping : ScriptBase, IMapping
11
14
  {
12
- public Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
15
+ public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
13
16
  {
14
17
  var httpTask = task as HttpTask;
15
18
  if (httpTask == null)
@@ -18,10 +21,36 @@ public class LoginForAddParticipantChatMapping : ScriptBase, IMapping
18
21
  var data = context.Instance?.Data;
19
22
  var newUserId = GetString(data, "newUserId");
20
23
  if (string.IsNullOrWhiteSpace(newUserId))
21
- return Task.FromResult(new ScriptResponse());
24
+ return new ScriptResponse();
22
25
 
23
- httpTask.SetBody(new { Username = newUserId.Trim() });
24
- return Task.FromResult(new ScriptResponse());
26
+ var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
27
+ if (string.IsNullOrWhiteSpace(secretName))
28
+ throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
29
+
30
+ var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
31
+ if (string.IsNullOrWhiteSpace(matrixBaseUrl))
32
+ throw new InvalidOperationException("MatrixBaseUrl secret is required");
33
+
34
+ var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
35
+ if (string.IsNullOrWhiteSpace(synapsePassword))
36
+ throw new InvalidOperationException("SynapsePassword secret is required");
37
+
38
+ var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/login";
39
+ httpTask.SetUrl(fullUrl);
40
+
41
+ httpTask.SetHeaders(new Dictionary<string, string>
42
+ {
43
+ ["Content-Type"] = "application/json",
44
+ ["Accept"] = "application/json"
45
+ });
46
+
47
+ httpTask.SetBody(new
48
+ {
49
+ type = "m.login.password",
50
+ identifier = new { type = "m.id.user", user = newUserId.Trim() },
51
+ password = synapsePassword
52
+ });
53
+ return new ScriptResponse();
25
54
  }
26
55
 
27
56
  public Task<ScriptResponse> OutputHandler(ScriptContext context)
@@ -35,8 +64,8 @@ public class LoginForAddParticipantChatMapping : ScriptBase, IMapping
35
64
  if (response?.isSuccess == true)
36
65
  {
37
66
  dynamic data = response.data;
38
- string sessionId = GetString(data, "sessionId");
39
- string userId = GetString(data, "userId");
67
+ string sessionId = GetString(data, "access_token");
68
+ string userId = GetString(data, "user_id");
40
69
  string username = GetString(data, "username");
41
70
 
42
71
  result.Data = new
@@ -0,0 +1,121 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using System.Threading.Tasks;
4
+ using BBT.Workflow.Scripting;
5
+ using BBT.Workflow.Definitions;
6
+
7
+ /// <summary>
8
+ /// Mapping for login-for-chat when used in chat-room workflow.
9
+ /// Calls POST /_matrix/client/v3/login on Synapse.
10
+ /// Logs in as data.user (the customer/room owner).
11
+ /// Stores access_token as sessionId in chatIntegration for subsequent Matrix API calls.
12
+ /// </summary>
13
+ public class LoginForChatRoomMapping : ScriptBase, IMapping
14
+ {
15
+ public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
16
+ {
17
+ var httpTask = task as HttpTask;
18
+ if (httpTask == null)
19
+ throw new InvalidOperationException("Task must be an HttpTask");
20
+
21
+ var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
22
+ if (string.IsNullOrWhiteSpace(secretName))
23
+ throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
24
+
25
+ var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
26
+ if (string.IsNullOrWhiteSpace(matrixBaseUrl))
27
+ throw new InvalidOperationException("MatrixBaseUrl secret is required");
28
+
29
+ var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
30
+ if (string.IsNullOrWhiteSpace(synapsePassword))
31
+ throw new InvalidOperationException("SynapsePassword secret is required");
32
+
33
+ var data = context.Instance?.Data;
34
+ var loginUsername = GetString(data, "user");
35
+ if (string.IsNullOrWhiteSpace(loginUsername))
36
+ throw new InvalidOperationException("Cannot determine login user: data.user is missing");
37
+
38
+ var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/login";
39
+ httpTask.SetUrl(fullUrl);
40
+
41
+ httpTask.SetHeaders(new Dictionary<string, string>
42
+ {
43
+ ["Content-Type"] = "application/json",
44
+ ["Accept"] = "application/json"
45
+ });
46
+
47
+ httpTask.SetBody(new
48
+ {
49
+ type = "m.login.password",
50
+ identifier = new { type = "m.id.user", user = "u" + loginUsername },
51
+ password = synapsePassword
52
+ });
53
+ return new ScriptResponse();
54
+ }
55
+
56
+ public Task<ScriptResponse> OutputHandler(ScriptContext context)
57
+ {
58
+ var result = new ScriptResponse();
59
+ var response = context.Body;
60
+ var instanceData = context.Instance?.Data;
61
+
62
+ string existingRoomId = null;
63
+ if (instanceData != null && HasProperty(instanceData, "chatIntegration") && instanceData.chatIntegration != null)
64
+ existingRoomId = GetString(instanceData.chatIntegration, "roomId");
65
+
66
+ if (response?.isSuccess == true)
67
+ {
68
+ dynamic data = response.data;
69
+ string sessionId = GetString(data, "access_token");
70
+ string userId = GetString(data, "user_id");
71
+ string username = GetString(data, "username");
72
+
73
+ result.Data = new
74
+ {
75
+ chatIntegration = new
76
+ {
77
+ sessionId,
78
+ userId,
79
+ username,
80
+ roomId = existingRoomId,
81
+ error = (string)null,
82
+ errorCode = (string)null
83
+ }
84
+ };
85
+ }
86
+ else
87
+ {
88
+ string errorMessage = response?.errorMessage?.ToString() ?? "Chat login failed";
89
+ string statusCode = response?.statusCode != null ? response.statusCode.ToString() : null;
90
+ result.Data = new
91
+ {
92
+ chatIntegration = new
93
+ {
94
+ sessionId = (string)null,
95
+ userId = (string)null,
96
+ username = (string)null,
97
+ roomId = existingRoomId,
98
+ error = errorMessage,
99
+ errorCode = statusCode
100
+ }
101
+ };
102
+ }
103
+
104
+ return Task.FromResult(result);
105
+ }
106
+
107
+ private string GetString(dynamic obj, string name)
108
+ {
109
+ if (obj == null) return null;
110
+ try
111
+ {
112
+ if (HasProperty(obj, name))
113
+ {
114
+ var v = GetPropertyValue(obj, name);
115
+ return v?.ToString();
116
+ }
117
+ }
118
+ catch { }
119
+ return null;
120
+ }
121
+ }