@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.
- package/burgan-tech-morph-touch-runtime-0.0.8.tgz +0 -0
- package/morph-touch/Functions/get-absence-entry.1.0.0.json +1 -1
- package/morph-touch/Functions/get-advisor-stats.1.0.0.json +1 -1
- package/morph-touch/Functions/get-available-slots.1.0.0.json +1 -1
- package/morph-touch/Functions/get-rezervations.1.0.0.json +1 -1
- package/morph-touch/Functions/src/GetAbsenceEntryMapping.csx +18 -4
- package/morph-touch/Functions/src/GetAdvisorStatsMapping.csx +22 -8
- package/morph-touch/Functions/src/GetAvailableSlotsMapping.csx +22 -14
- package/morph-touch/Functions/src/GetRezervationsMapping.csx +46 -9
- package/morph-touch/Functions/src/SendCancelNotificationMapping.csx +27 -2
- package/morph-touch/Tasks/login-for-chat.1.0.0.json +27 -0
- package/morph-touch/Tasks/register-for-chat.1.0.0.json +27 -0
- package/morph-touch/Workflows/chat-room.json +273 -14
- package/morph-touch/Workflows/notification-sender.json +2 -2
- package/morph-touch/Workflows/rezervation-start.json +39 -2
- package/morph-touch/Workflows/rezervation-transfer.json +44 -7
- package/morph-touch/Workflows/rezervation-update.json +4 -4
- package/morph-touch/Workflows/rezervation.json +135 -45
- package/morph-touch/Workflows/src/CanStartRezervationTimerMapping.csx +18 -3
- package/morph-touch/Workflows/src/ChatRoomRemoveMapping.csx +10 -1
- package/morph-touch/Workflows/src/ChatRoomTransferInviteMapping.csx +10 -1
- package/morph-touch/Workflows/src/ChatRoomTransferRemoveMapping.csx +9 -1
- package/morph-touch/Workflows/src/ChatRoomUpdateMapping.csx +10 -1
- package/morph-touch/Workflows/src/CheckDuplicateRezervationMapping.csx +17 -3
- package/morph-touch/Workflows/src/CheckRandevuTimeMapping.csx +16 -2
- package/morph-touch/Workflows/src/CreateChatRoomForRezervationMapping.csx +12 -2
- package/morph-touch/Workflows/src/CreatePermanentChatRoomMapping.csx +11 -1
- package/morph-touch/Workflows/src/EnrichRezervationsForTransferMapping.csx +18 -4
- package/morph-touch/Workflows/src/FetchRoomMessagesForSummaryMapping.csx +10 -2
- package/morph-touch/Workflows/src/InviteAdvisorForRandevuUpdateMapping.csx +10 -1
- package/morph-touch/Workflows/src/InviteNewAdvisorToRezervationRoomMapping.csx +11 -2
- package/morph-touch/Workflows/src/InviteNewParticipantToRandevuRoomMapping.csx +10 -1
- package/morph-touch/Workflows/src/JoinChatRoomForAddParticipantMapping.csx +5 -1
- package/morph-touch/Workflows/src/JoinChatRoomForRandevuStartMapping.csx +5 -1
- package/morph-touch/Workflows/src/JoinChatRoomForRezervationMapping.csx +4 -0
- package/morph-touch/Workflows/src/JoinMatrixRoomMapping.csx +11 -1
- package/morph-touch/Workflows/src/JoinUserToRoomMapping.csx +6 -0
- package/morph-touch/Workflows/src/LoginForAddParticipantChatMapping.csx +35 -6
- package/morph-touch/Workflows/src/LoginForChatRoomMapping.csx +121 -0
- package/morph-touch/Workflows/src/LoginForJoinUserToRoomMapping.csx +142 -0
- package/morph-touch/Workflows/src/LoginForRandevuStartChatMapping.csx +35 -10
- package/morph-touch/Workflows/src/LoginForTransferChatMapping.csx +153 -0
- package/morph-touch/Workflows/src/RegisterForAddParticipantChatMapping.csx +74 -0
- package/morph-touch/Workflows/src/RegisterForChatRoomMapping.csx +74 -0
- package/morph-touch/Workflows/src/RegisterForJoinUserToRoomMapping.csx +87 -0
- package/morph-touch/Workflows/src/RegisterForRandevuStartChatMapping.csx +80 -0
- package/morph-touch/Workflows/src/RegisterForTransferChatMapping.csx +113 -0
- package/morph-touch/Workflows/src/SendPushNotificationMapping.csx +25 -4
- package/morph-touch/Workflows/src/SendSmsNotificationMapping.csx +25 -4
- package/morph-touch/Workflows/src/SendSummaryToNewRoomMapping.csx +10 -2
- package/morph-touch/Workflows/src/SetRoomHistoryVisibilityMapping.csx +12 -4
- package/morph-touch/Workflows/src/ValidateDateForRezervationMapping.csx +16 -2
- package/morph-touch/Workflows/src/ValidateSlotForRandevuUpdateMapping.csx +22 -15
- package/morph-touch/Workflows/src/ValidateSlotForRezervationMapping.csx +23 -16
- package/morph-touch/Workflows/src/ValidateTransferMapping.csx +16 -2
- package/morph-touch/doc/morph-touch-domain.en.md +420 -6
- package/morph-touch/doc/morph-touch-domain.md +423 -6
- package/package.json +1 -1
- package/vnext.config.json +1 -1
- package/burgan-tech-morph-touch-runtime-0.0.6.tgz +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
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 the next step is join-user-to-room.
|
|
9
|
+
/// Logs in as the user who will join the room (pendingJoinUserId / newAdvisorId / advisorId).
|
|
10
|
+
/// Stores access_token in chatIntegration.joinSessionId so JoinUserToRoomMapping
|
|
11
|
+
/// uses the correct token without overwriting the room-owner's sessionId.
|
|
12
|
+
/// </summary>
|
|
13
|
+
public class LoginForJoinUserToRoomMapping : 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 data = context.Instance?.Data;
|
|
22
|
+
|
|
23
|
+
var joinUser = GetString(data, "pendingJoinUserId");
|
|
24
|
+
if (string.IsNullOrWhiteSpace(joinUser))
|
|
25
|
+
joinUser = GetString(data, "newAdvisorId");
|
|
26
|
+
if (string.IsNullOrWhiteSpace(joinUser))
|
|
27
|
+
joinUser = GetString(data, "advisorId");
|
|
28
|
+
|
|
29
|
+
if (string.IsNullOrWhiteSpace(joinUser))
|
|
30
|
+
return new ScriptResponse();
|
|
31
|
+
|
|
32
|
+
var loginUsername = joinUser.Trim();
|
|
33
|
+
if (loginUsername.StartsWith("@"))
|
|
34
|
+
{
|
|
35
|
+
var colonIdx = loginUsername.IndexOf(':');
|
|
36
|
+
loginUsername = colonIdx > 0 ? loginUsername.Substring(1, colonIdx - 1) : loginUsername.Substring(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
|
|
40
|
+
if (string.IsNullOrWhiteSpace(secretName))
|
|
41
|
+
throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
|
|
42
|
+
|
|
43
|
+
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
44
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
45
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
46
|
+
|
|
47
|
+
var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
|
|
48
|
+
if (string.IsNullOrWhiteSpace(synapsePassword))
|
|
49
|
+
throw new InvalidOperationException("SynapsePassword secret is required");
|
|
50
|
+
|
|
51
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/login";
|
|
52
|
+
httpTask.SetUrl(fullUrl);
|
|
53
|
+
|
|
54
|
+
httpTask.SetHeaders(new Dictionary<string, string>
|
|
55
|
+
{
|
|
56
|
+
["Content-Type"] = "application/json",
|
|
57
|
+
["Accept"] = "application/json"
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
httpTask.SetBody(new
|
|
61
|
+
{
|
|
62
|
+
type = "m.login.password",
|
|
63
|
+
identifier = new { type = "m.id.user", user = loginUsername },
|
|
64
|
+
password = synapsePassword
|
|
65
|
+
});
|
|
66
|
+
return new ScriptResponse();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
70
|
+
{
|
|
71
|
+
var result = new ScriptResponse();
|
|
72
|
+
var response = context.Body;
|
|
73
|
+
var instanceData = context.Instance?.Data;
|
|
74
|
+
|
|
75
|
+
string existingSessionId = null;
|
|
76
|
+
string existingUserId = null;
|
|
77
|
+
string existingUsername = null;
|
|
78
|
+
string existingRoomId = null;
|
|
79
|
+
if (instanceData != null && HasProperty(instanceData, "chatIntegration") && instanceData.chatIntegration != null)
|
|
80
|
+
{
|
|
81
|
+
existingSessionId = GetString(instanceData.chatIntegration, "sessionId");
|
|
82
|
+
existingUserId = GetString(instanceData.chatIntegration, "userId");
|
|
83
|
+
existingUsername = GetString(instanceData.chatIntegration, "username");
|
|
84
|
+
existingRoomId = GetString(instanceData.chatIntegration, "roomId");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (response?.isSuccess == true)
|
|
88
|
+
{
|
|
89
|
+
dynamic data = response.data;
|
|
90
|
+
string joinSessionId = GetString(data, "access_token");
|
|
91
|
+
|
|
92
|
+
result.Data = new
|
|
93
|
+
{
|
|
94
|
+
chatIntegration = new
|
|
95
|
+
{
|
|
96
|
+
sessionId = existingSessionId,
|
|
97
|
+
userId = existingUserId,
|
|
98
|
+
username = existingUsername,
|
|
99
|
+
roomId = existingRoomId,
|
|
100
|
+
joinSessionId,
|
|
101
|
+
error = (string)null,
|
|
102
|
+
errorCode = (string)null
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
else
|
|
107
|
+
{
|
|
108
|
+
string errorMessage = response?.errorMessage?.ToString() ?? "Join user login failed";
|
|
109
|
+
string statusCode = response?.statusCode != null ? response.statusCode.ToString() : null;
|
|
110
|
+
result.Data = new
|
|
111
|
+
{
|
|
112
|
+
chatIntegration = new
|
|
113
|
+
{
|
|
114
|
+
sessionId = existingSessionId,
|
|
115
|
+
userId = existingUserId,
|
|
116
|
+
username = existingUsername,
|
|
117
|
+
roomId = existingRoomId,
|
|
118
|
+
joinSessionId = (string)null,
|
|
119
|
+
error = errorMessage,
|
|
120
|
+
errorCode = statusCode
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return Task.FromResult(result);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private string GetString(dynamic obj, string name)
|
|
129
|
+
{
|
|
130
|
+
if (obj == null) return null;
|
|
131
|
+
try
|
|
132
|
+
{
|
|
133
|
+
if (HasProperty(obj, name))
|
|
134
|
+
{
|
|
135
|
+
var v = GetPropertyValue(obj, name);
|
|
136
|
+
return v?.ToString();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch { }
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -1,20 +1,35 @@
|
|
|
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 rezervation-start flow.
|
|
9
|
+
/// Calls POST /_matrix/client/v3/login on Synapse.
|
|
8
10
|
/// Uses participantType to determine login user: advisor, customer (user), or invited (invitedUserId).
|
|
11
|
+
/// Stores access_token as sessionId in chatIntegration for subsequent Matrix API calls.
|
|
9
12
|
/// </summary>
|
|
10
13
|
public class LoginForRandevuStartChatMapping : 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)
|
|
16
19
|
throw new InvalidOperationException("Task must be an HttpTask");
|
|
17
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
|
+
|
|
18
33
|
var data = context.Instance?.Data;
|
|
19
34
|
var participantType = GetString(data, "participantType");
|
|
20
35
|
var user = GetString(data, "user");
|
|
@@ -22,12 +37,26 @@ public class LoginForRandevuStartChatMapping : ScriptBase, IMapping
|
|
|
22
37
|
|
|
23
38
|
var loginUsername = participantType == "advisor" ? advisor
|
|
24
39
|
: participantType == "invited" ? GetString(data, "invitedUserId")
|
|
25
|
-
: user;
|
|
40
|
+
: "u"+user;
|
|
26
41
|
if (string.IsNullOrWhiteSpace(loginUsername))
|
|
27
42
|
throw new InvalidOperationException("Cannot determine login user: participantType, user, advisor, or invitedUserId missing");
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/login";
|
|
45
|
+
httpTask.SetUrl(fullUrl);
|
|
46
|
+
|
|
47
|
+
httpTask.SetHeaders(new Dictionary<string, string>
|
|
48
|
+
{
|
|
49
|
+
["Content-Type"] = "application/json",
|
|
50
|
+
["Accept"] = "application/json"
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
httpTask.SetBody(new
|
|
54
|
+
{
|
|
55
|
+
type = "m.login.password",
|
|
56
|
+
identifier = new { type = "m.id.user", user = loginUsername },
|
|
57
|
+
password = synapsePassword
|
|
58
|
+
});
|
|
59
|
+
return new ScriptResponse();
|
|
31
60
|
}
|
|
32
61
|
|
|
33
62
|
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
@@ -38,14 +67,10 @@ public class LoginForRandevuStartChatMapping : ScriptBase, IMapping
|
|
|
38
67
|
if (response?.isSuccess == true)
|
|
39
68
|
{
|
|
40
69
|
dynamic data = response.data;
|
|
41
|
-
string sessionId = GetString(data, "
|
|
42
|
-
string userId = GetString(data, "
|
|
70
|
+
string sessionId = GetString(data, "access_token");
|
|
71
|
+
string userId = GetString(data, "user_id");
|
|
43
72
|
string username = GetString(data, "username");
|
|
44
73
|
|
|
45
|
-
var instanceData = context.Instance?.Data;
|
|
46
|
-
// var existingChat = instanceData?.chatIntegration;
|
|
47
|
-
// string roomId = GetString(existingChat, "roomId");
|
|
48
|
-
|
|
49
74
|
result.Data = new
|
|
50
75
|
{
|
|
51
76
|
chatIntegration = new
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Threading.Tasks;
|
|
5
|
+
using BBT.Workflow.Scripting;
|
|
6
|
+
using BBT.Workflow.Definitions;
|
|
7
|
+
|
|
8
|
+
/// <summary>
|
|
9
|
+
/// Mapping for login-for-chat when used in rezervation-transfer flow.
|
|
10
|
+
/// Calls POST /_matrix/client/v3/login on Synapse.
|
|
11
|
+
/// Looks up user from permanentChatRooms by chatRoomKey (same logic as FetchRoomMessagesForSummaryMapping).
|
|
12
|
+
/// Stores access_token as sessionId in chatIntegration for subsequent Matrix API calls.
|
|
13
|
+
/// </summary>
|
|
14
|
+
public class LoginForTransferChatMapping : ScriptBase, IMapping
|
|
15
|
+
{
|
|
16
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
17
|
+
{
|
|
18
|
+
var httpTask = task as HttpTask;
|
|
19
|
+
if (httpTask == null)
|
|
20
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
21
|
+
|
|
22
|
+
var data = context.Instance?.Data;
|
|
23
|
+
if (data == null)
|
|
24
|
+
return new ScriptResponse();
|
|
25
|
+
|
|
26
|
+
string user = null;
|
|
27
|
+
var permanentRoomPlan = data.permanentRoomPlan;
|
|
28
|
+
if (permanentRoomPlan != null)
|
|
29
|
+
{
|
|
30
|
+
int processedIndex = 0;
|
|
31
|
+
if (HasProperty(data, "permanentProcessedIndex"))
|
|
32
|
+
int.TryParse(data.permanentProcessedIndex?.ToString() ?? "0", out processedIndex);
|
|
33
|
+
|
|
34
|
+
var items = permanentRoomPlan as IEnumerable<object>;
|
|
35
|
+
if (items != null)
|
|
36
|
+
{
|
|
37
|
+
var itemsList = items.ToList();
|
|
38
|
+
if (processedIndex < itemsList.Count)
|
|
39
|
+
{
|
|
40
|
+
dynamic currentItem = itemsList[processedIndex];
|
|
41
|
+
var chatRoomKey = currentItem?.chatRoomKey?.ToString();
|
|
42
|
+
if (!string.IsNullOrEmpty(chatRoomKey))
|
|
43
|
+
user = LookupUser(data, chatRoomKey);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (string.IsNullOrWhiteSpace(user))
|
|
49
|
+
return new ScriptResponse();
|
|
50
|
+
|
|
51
|
+
var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
|
|
52
|
+
if (string.IsNullOrWhiteSpace(secretName))
|
|
53
|
+
throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
|
|
54
|
+
|
|
55
|
+
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
56
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
57
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
58
|
+
|
|
59
|
+
var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
|
|
60
|
+
if (string.IsNullOrWhiteSpace(synapsePassword))
|
|
61
|
+
throw new InvalidOperationException("SynapsePassword secret is required");
|
|
62
|
+
|
|
63
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/login";
|
|
64
|
+
httpTask.SetUrl(fullUrl);
|
|
65
|
+
|
|
66
|
+
httpTask.SetHeaders(new Dictionary<string, string>
|
|
67
|
+
{
|
|
68
|
+
["Content-Type"] = "application/json",
|
|
69
|
+
["Accept"] = "application/json"
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
httpTask.SetBody(new
|
|
73
|
+
{
|
|
74
|
+
type = "m.login.password",
|
|
75
|
+
identifier = new { type = "m.id.user", user = user },
|
|
76
|
+
password = synapsePassword
|
|
77
|
+
});
|
|
78
|
+
return new ScriptResponse();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
82
|
+
{
|
|
83
|
+
var result = new ScriptResponse();
|
|
84
|
+
var response = context.Body;
|
|
85
|
+
|
|
86
|
+
if (response?.isSuccess == true)
|
|
87
|
+
{
|
|
88
|
+
dynamic data = response.data;
|
|
89
|
+
string sessionId = GetString(data, "access_token");
|
|
90
|
+
string userId = GetString(data, "user_id");
|
|
91
|
+
string username = GetString(data, "username");
|
|
92
|
+
|
|
93
|
+
result.Data = new
|
|
94
|
+
{
|
|
95
|
+
chatIntegration = new
|
|
96
|
+
{
|
|
97
|
+
sessionId,
|
|
98
|
+
userId,
|
|
99
|
+
username,
|
|
100
|
+
error = (string)null,
|
|
101
|
+
errorCode = (string)null
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
else
|
|
106
|
+
{
|
|
107
|
+
string errorMessage = response?.errorMessage?.ToString() ?? "Chat login failed";
|
|
108
|
+
string statusCode = response?.statusCode != null ? response.statusCode.ToString() : null;
|
|
109
|
+
result.Data = new
|
|
110
|
+
{
|
|
111
|
+
chatIntegration = new
|
|
112
|
+
{
|
|
113
|
+
sessionId = (string)null,
|
|
114
|
+
userId = (string)null,
|
|
115
|
+
username = (string)null,
|
|
116
|
+
error = errorMessage,
|
|
117
|
+
errorCode = statusCode
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return Task.FromResult(result);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private string LookupUser(dynamic data, string chatRoomKey)
|
|
126
|
+
{
|
|
127
|
+
if (!HasProperty(data, "permanentChatRooms") || data.permanentChatRooms == null)
|
|
128
|
+
return null;
|
|
129
|
+
|
|
130
|
+
foreach (var room in data.permanentChatRooms)
|
|
131
|
+
{
|
|
132
|
+
var key = GetString(room, "chatRoomKey");
|
|
133
|
+
if (string.Equals(key, chatRoomKey, StringComparison.OrdinalIgnoreCase))
|
|
134
|
+
return GetString(room, "user");
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private string GetString(dynamic obj, string name)
|
|
140
|
+
{
|
|
141
|
+
if (obj == null) return null;
|
|
142
|
+
try
|
|
143
|
+
{
|
|
144
|
+
if (HasProperty(obj, name))
|
|
145
|
+
{
|
|
146
|
+
var v = GetPropertyValue(obj, name);
|
|
147
|
+
return v?.ToString()?.Trim();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch { }
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
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 register-for-chat in add-participant flow.
|
|
9
|
+
/// Registers newUserId on Synapse via POST /_matrix/client/v3/register.
|
|
10
|
+
/// ErrorBoundary on the task ignores M_USER_IN_USE and other errors so login proceeds.
|
|
11
|
+
/// </summary>
|
|
12
|
+
public class RegisterForAddParticipantChatMapping : ScriptBase, IMapping
|
|
13
|
+
{
|
|
14
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
15
|
+
{
|
|
16
|
+
var httpTask = task as HttpTask;
|
|
17
|
+
if (httpTask == null)
|
|
18
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
19
|
+
|
|
20
|
+
var data = context.Instance?.Data;
|
|
21
|
+
var newUserId = GetString(data, "newUserId");
|
|
22
|
+
if (string.IsNullOrWhiteSpace(newUserId))
|
|
23
|
+
return new ScriptResponse();
|
|
24
|
+
|
|
25
|
+
var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
|
|
26
|
+
if (string.IsNullOrWhiteSpace(secretName))
|
|
27
|
+
throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
|
|
28
|
+
|
|
29
|
+
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
30
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
31
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
32
|
+
|
|
33
|
+
var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
|
|
34
|
+
if (string.IsNullOrWhiteSpace(synapsePassword))
|
|
35
|
+
throw new InvalidOperationException("SynapsePassword secret is required");
|
|
36
|
+
|
|
37
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/register";
|
|
38
|
+
httpTask.SetUrl(fullUrl);
|
|
39
|
+
|
|
40
|
+
httpTask.SetHeaders(new Dictionary<string, string>
|
|
41
|
+
{
|
|
42
|
+
["Content-Type"] = "application/json",
|
|
43
|
+
["Accept"] = "application/json"
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
httpTask.SetBody(new
|
|
47
|
+
{
|
|
48
|
+
auth = new { type = "m.login.dummy" },
|
|
49
|
+
username = newUserId.Trim(),
|
|
50
|
+
password = synapsePassword
|
|
51
|
+
});
|
|
52
|
+
return new ScriptResponse();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
56
|
+
{
|
|
57
|
+
return Task.FromResult(new ScriptResponse());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private string GetString(dynamic obj, string name)
|
|
61
|
+
{
|
|
62
|
+
if (obj == null) return null;
|
|
63
|
+
try
|
|
64
|
+
{
|
|
65
|
+
if (HasProperty(obj, name))
|
|
66
|
+
{
|
|
67
|
+
var v = GetPropertyValue(obj, name);
|
|
68
|
+
return v?.ToString();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
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 register-for-chat in chat-room workflow.
|
|
9
|
+
/// Registers data.user on Synapse via POST /_matrix/client/v3/register.
|
|
10
|
+
/// ErrorBoundary on the task ignores M_USER_IN_USE and other errors so login proceeds.
|
|
11
|
+
/// </summary>
|
|
12
|
+
public class RegisterForChatRoomMapping : ScriptBase, IMapping
|
|
13
|
+
{
|
|
14
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
15
|
+
{
|
|
16
|
+
var httpTask = task as HttpTask;
|
|
17
|
+
if (httpTask == null)
|
|
18
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
19
|
+
|
|
20
|
+
var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
|
|
21
|
+
if (string.IsNullOrWhiteSpace(secretName))
|
|
22
|
+
throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
|
|
23
|
+
|
|
24
|
+
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
25
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
26
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
27
|
+
|
|
28
|
+
var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
|
|
29
|
+
if (string.IsNullOrWhiteSpace(synapsePassword))
|
|
30
|
+
throw new InvalidOperationException("SynapsePassword secret is required");
|
|
31
|
+
|
|
32
|
+
var data = context.Instance?.Data;
|
|
33
|
+
var registerUsername = GetString(data, "user");
|
|
34
|
+
if (string.IsNullOrWhiteSpace(registerUsername))
|
|
35
|
+
throw new InvalidOperationException("Cannot determine register user: data.user is missing");
|
|
36
|
+
|
|
37
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/register";
|
|
38
|
+
httpTask.SetUrl(fullUrl);
|
|
39
|
+
|
|
40
|
+
httpTask.SetHeaders(new Dictionary<string, string>
|
|
41
|
+
{
|
|
42
|
+
["Content-Type"] = "application/json",
|
|
43
|
+
["Accept"] = "application/json"
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
httpTask.SetBody(new
|
|
47
|
+
{
|
|
48
|
+
auth = new { type = "m.login.dummy" },
|
|
49
|
+
username = "u" + registerUsername,
|
|
50
|
+
password = synapsePassword
|
|
51
|
+
});
|
|
52
|
+
return new ScriptResponse();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
56
|
+
{
|
|
57
|
+
return Task.FromResult(new ScriptResponse());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private string GetString(dynamic obj, string name)
|
|
61
|
+
{
|
|
62
|
+
if (obj == null) return null;
|
|
63
|
+
try
|
|
64
|
+
{
|
|
65
|
+
if (HasProperty(obj, name))
|
|
66
|
+
{
|
|
67
|
+
var v = GetPropertyValue(obj, name);
|
|
68
|
+
return v?.ToString();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
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 register-for-chat before join-user-to-room.
|
|
9
|
+
/// Registers the joining user (pendingJoinUserId / newAdvisorId / advisorId) on Synapse.
|
|
10
|
+
/// ErrorBoundary on the task ignores M_USER_IN_USE and other errors so login proceeds.
|
|
11
|
+
/// </summary>
|
|
12
|
+
public class RegisterForJoinUserToRoomMapping : ScriptBase, IMapping
|
|
13
|
+
{
|
|
14
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
15
|
+
{
|
|
16
|
+
var httpTask = task as HttpTask;
|
|
17
|
+
if (httpTask == null)
|
|
18
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
19
|
+
|
|
20
|
+
var data = context.Instance?.Data;
|
|
21
|
+
|
|
22
|
+
var joinUser = GetString(data, "pendingJoinUserId");
|
|
23
|
+
if (string.IsNullOrWhiteSpace(joinUser))
|
|
24
|
+
joinUser = GetString(data, "newAdvisorId");
|
|
25
|
+
if (string.IsNullOrWhiteSpace(joinUser))
|
|
26
|
+
joinUser = GetString(data, "advisorId");
|
|
27
|
+
|
|
28
|
+
if (string.IsNullOrWhiteSpace(joinUser))
|
|
29
|
+
return new ScriptResponse();
|
|
30
|
+
|
|
31
|
+
var registerUsername = joinUser.Trim();
|
|
32
|
+
if (registerUsername.StartsWith("@"))
|
|
33
|
+
{
|
|
34
|
+
var colonIdx = registerUsername.IndexOf(':');
|
|
35
|
+
registerUsername = colonIdx > 0 ? registerUsername.Substring(1, colonIdx - 1) : registerUsername.Substring(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
|
|
39
|
+
if (string.IsNullOrWhiteSpace(secretName))
|
|
40
|
+
throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
|
|
41
|
+
|
|
42
|
+
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
43
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
44
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
45
|
+
|
|
46
|
+
var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
|
|
47
|
+
if (string.IsNullOrWhiteSpace(synapsePassword))
|
|
48
|
+
throw new InvalidOperationException("SynapsePassword secret is required");
|
|
49
|
+
|
|
50
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/register";
|
|
51
|
+
httpTask.SetUrl(fullUrl);
|
|
52
|
+
|
|
53
|
+
httpTask.SetHeaders(new Dictionary<string, string>
|
|
54
|
+
{
|
|
55
|
+
["Content-Type"] = "application/json",
|
|
56
|
+
["Accept"] = "application/json"
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
httpTask.SetBody(new
|
|
60
|
+
{
|
|
61
|
+
auth = new { type = "m.login.dummy" },
|
|
62
|
+
username = registerUsername,
|
|
63
|
+
password = synapsePassword
|
|
64
|
+
});
|
|
65
|
+
return new ScriptResponse();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
69
|
+
{
|
|
70
|
+
return Task.FromResult(new ScriptResponse());
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private string GetString(dynamic obj, string name)
|
|
74
|
+
{
|
|
75
|
+
if (obj == null) return null;
|
|
76
|
+
try
|
|
77
|
+
{
|
|
78
|
+
if (HasProperty(obj, name))
|
|
79
|
+
{
|
|
80
|
+
var v = GetPropertyValue(obj, name);
|
|
81
|
+
return v?.ToString();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch { }
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|