23 public PushRuleDefinition(
MessageType messageType,
string localName,
string @
namespace,
string channel,
string messageVariable,
string patternScript,
string contentScript)
25 this.MessageType = messageType;
26 this.LocalName = localName;
27 this.Namespace = @
namespace;
28 this.Channel = channel;
29 this.MessageVariable = messageVariable;
30 this.PatternScript = patternScript;
31 this.ContentScript = contentScript;
78 public static IReadOnlyList<PushRuleDefinition>
All {
get; } = Build();
85 private static IReadOnlyList<PushRuleDefinition> Build()
87 List<PushRuleDefinition> Definitions =
new();
136 "FromJid:=GetAttribute(Stanza,'from');",
137 "ToJid:=GetAttribute(Stanza,'to');",
138 "FriendlyName:=RosterName(ToJid,FromJid);",
139 "Content:=GetElement(Stanza,'content');",
140 $
"TitleText:='{NotificationChatTitle}';",
141 $
"BodyText:='{NotificationChatBody}';",
143 "'payloadKind': 'PushNotificationPayload',",
144 "'payloadVersion': 1,",
145 "'visual': { 'title': Replace(TitleText,'{0}',FriendlyName), 'body': BodyText },",
146 $
"'action': {{ 'type': '{NotificationAction.OpenChat}', 'entityId': FromJid, 'correlationId': FromJid }},",
147 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Messages}' }},",
148 "'delivery': { 'priority': 'High', 'silent': false },",
149 "'context': { 'fromJid': FromJid, 'toJid': ToJid, 'rosterName': FriendlyName },",
150 "'data': { 'isObject': exists(Content) and !empty(Markdown:= InnerText(Content)) and (Left(Markdown,2)='![' or (Left(Markdown,3)='```' and Right(Markdown,3)='```')) }",
155 "petitionIdentityMsg",
161 "E:=GetElement(Stanza,'petitionIdentityMsg');",
162 "ToJid:=GetAttribute(Stanza,'to');",
163 "FromJid:=GetAttribute(E,'from');",
164 "FriendlyName:=RosterName(ToJid,FromJid);",
165 $
"TitleText:='{NotificationPetitionIdentityTitle}';",
166 $
"BodyText:='{NotificationPetitionIdentityBody}';",
168 "'payloadKind': 'PushNotificationPayload',",
169 "'payloadVersion': 1,",
170 "'visual': { 'title': Replace(TitleText,'{0}',FriendlyName), 'body': BodyText },",
171 $
"'action': {{ 'type': '{NotificationAction.OpenProfile}', 'entityId': FromJid, 'correlationId': GetAttribute(E,'petitionId') }},",
172 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Petitions}' }},",
173 "'delivery': { 'priority': 'High' },",
174 "'context': { 'fromJid': FromJid, 'toJid': ToJid, 'rosterName': FriendlyName },",
175 "'data': { 'petitionId': GetAttribute(E,'petitionId') }",
180 "petitionContractMsg",
186 "E:=GetElement(Stanza,'petitionContractMsg');",
187 "ToJid:=GetAttribute(Stanza,'to');",
188 "FromJid:=GetAttribute(E,'from');",
189 "FriendlyName:=RosterName(ToJid,FromJid);",
190 $
"TitleText:='{NotificationPetitionContractTitle}';",
191 $
"BodyText:='{NotificationPetitionContractBody}';",
193 "'payloadKind': 'PushNotificationPayload',",
194 "'payloadVersion': 1,",
195 "'visual': { 'title': Replace(TitleText,'{0}',FriendlyName), 'body': BodyText },",
196 $
"'action': {{ 'type': '{NotificationAction.OpenProfile}', 'entityId': FromJid, 'correlationId': GetAttribute(E,'petitionId') }},",
197 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Petitions}' }},",
198 "'delivery': { 'priority': 'High' },",
199 "'context': { 'fromJid': FromJid, 'toJid': ToJid, 'rosterName': FriendlyName },",
200 "'data': { 'petitionId': GetAttribute(E,'petitionId') }",
205 "petitionSignatureMsg",
211 "E:=GetElement(Stanza,'petitionSignatureMsg');",
212 "ToJid:=GetAttribute(Stanza,'to');",
213 "FromJid:=GetAttribute(E,'from');",
214 "FriendlyName:=RosterName(ToJid,FromJid);",
215 $
"TitleText:='{NotificationPetitionSignatureTitle}';",
216 $
"BodyText:='{NotificationPetitionSignatureBody}';",
218 "'payloadKind': 'PushNotificationPayload',",
219 "'payloadVersion': 1,",
220 "'visual': { 'title': Replace(TitleText,'{0}',FriendlyName), 'body': BodyText },",
221 $
"'action': {{ 'type': '{NotificationAction.OpenProfile}', 'entityId': FromJid, 'correlationId': GetAttribute(E,'petitionId') }},",
222 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Petitions}' }},",
223 "'delivery': { 'priority': 'High' },",
224 "'context': { 'fromJid': FromJid, 'toJid': ToJid, 'rosterName': FriendlyName },",
225 "'data': { 'petitionId': GetAttribute(E,'petitionId') }",
236 "E:=GetElement(Stanza,'identity');",
237 "Status:=GetElement(E,'status');",
238 "State:=GetAttribute(Status,'state');",
239 "if (State='Approved') then",
241 "'payloadKind': 'PushNotificationPayload',",
242 "'payloadVersion': 1,",
243 $
"'visual': {{ 'title': '{NotificationIdentityApprovedTitle}', 'body': '{NotificationIdentityApprovedBody}' }},",
244 $
"'action': {{ 'type': '{NotificationAction.OpenIdentity}', navigationTarget: '{NotificationAction.OpenIdentity}', 'entityId': GetAttribute(E,'id'), 'correlationId': GetAttribute(E,'id') }},",
245 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Identities}' }},",
246 "'delivery': { 'priority': 'High' },",
247 "'context': { 'provider': GetAttribute(Status,'provider') },",
248 "'data': { 'legalId': GetAttribute(E,'id'), 'state': State, 'validFrom': GetAttribute(Status,'from'), 'validTo': GetAttribute(Status,'to') }",
250 "else if (State='Obsoleted') then",
252 "'payloadKind': 'PushNotificationPayload',",
253 "'payloadVersion': 1,",
254 $
"'visual': {{ 'title': '{NotificationIdentityObsoletedTitle}', 'body': '{NotificationIdentityObsoletedBody}' }},",
255 $
"'action': {{ 'type': '{NotificationAction.OpenIdentity}', navigationTarget: '{NotificationAction.OpenIdentity}', 'entityId': GetAttribute(E,'id'), 'correlationId': GetAttribute(E,'id') }},",
256 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Identities}' }},",
257 "'delivery': { 'priority': 'High' },",
258 "'context': { 'provider': GetAttribute(Status,'provider') },",
259 "'data': { 'legalId': GetAttribute(E,'id'), 'state': State, 'validFrom': GetAttribute(Status,'from'), 'validTo': GetAttribute(Status,'to') }",
261 "else if (State='Rejected') then",
263 "'payloadKind': 'PushNotificationPayload',",
264 "'payloadVersion': 1,",
265 $
"'visual': {{ 'title': '{NotificationIdentityRejectedTitle}', 'body': '{NotificationIdentityRejectedBody}' }},",
266 $
"'action': {{ 'type': '{NotificationAction.OpenIdentity}', navigationTarget: '{NotificationAction.OpenIdentity}', 'entityId': GetAttribute(E,'id'), 'correlationId': GetAttribute(E,'id') }},",
267 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Identities}' }},",
268 "'delivery': { 'priority': 'High' },",
269 "'context': { 'provider': GetAttribute(Status,'provider') },",
270 "'data': { 'legalId': GetAttribute(E,'id'), 'state': State, 'validFrom': GetAttribute(Status,'from'), 'validTo': GetAttribute(Status,'to') }",
272 "else if (State='Compromised') then",
274 "'payloadKind': 'PushNotificationPayload',",
275 "'payloadVersion': 1,",
276 $
"'visual': {{ 'title': '{NotificationIdentityCompromisedTitle}', 'body': '{NotificationIdentityCompromisedBody}' }},",
277 $
"'action': {{ 'type': '{NotificationAction.OpenIdentity}', navigationTarget: '{NotificationAction.OpenIdentity}', 'entityId': GetAttribute(E,'id'), 'correlationId': GetAttribute(E,'id') }},",
278 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Identities}' }},",
279 "'delivery': { 'priority': 'High' },",
280 "'context': { 'provider': GetAttribute(Status,'provider') },",
281 "'data': { 'legalId': GetAttribute(E,'id'), 'state': State, 'validFrom': GetAttribute(Status,'from'), 'validTo': GetAttribute(Status,'to') }",
294 "E:=GetElement(Stanza,'contractCreated');",
296 "'payloadKind': 'PushNotificationPayload',",
297 "'payloadVersion': 1,",
298 $
"'visual': {{ 'title': '{NotificationContractCreatedTitle}', 'body': '{NotificationContractCreatedBody}' }},",
299 $
"'action': {{ 'type': '{NotificationAction.OpenContract}', 'entityId': GetAttribute(E,'contractId'), 'correlationId': GetAttribute(E,'contractId') }},",
300 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Contracts}' }},",
301 "'delivery': { 'priority': 'High' },",
302 "'data': { 'contractId': GetAttribute(E,'contractId') }",
313 "E:=GetElement(Stanza,'contractSigned');",
315 "'payloadKind': 'PushNotificationPayload',",
316 "'payloadVersion': 1,",
317 $
"'visual': {{ 'title': '{NotificationContractSignedTitle}', 'body': '{NotificationContractSignedBody}' }},",
318 $
"'action': {{ 'type': '{NotificationAction.OpenContract}', 'entityId': GetAttribute(E,'contractId'), 'correlationId': GetAttribute(E,'contractId') }},",
319 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Contracts}' }},",
320 "'delivery': { 'priority': 'High' },",
321 "'data': { 'contractId': GetAttribute(E,'contractId'), 'legalId': GetAttribute(E,'legalId') }",
332 "E:=GetElement(Stanza,'contractUpdated');",
334 "'payloadKind': 'PushNotificationPayload',",
335 "'payloadVersion': 1,",
336 $
"'visual': {{ 'title': '{NotificationContractUpdatedTitle}', 'body': '{NotificationContractUpdatedBody}' }},",
337 $
"'action': {{ 'type': '{NotificationAction.OpenContract}', 'entityId': GetAttribute(E,'contractId'), 'correlationId': GetAttribute(E,'contractId') }},",
338 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Contracts}' }},",
339 "'delivery': { 'priority': 'High' },",
340 "'data': { 'contractId': GetAttribute(E,'contractId') }",
351 "E:=GetElement(Stanza,'contractDeleted');",
353 "'payloadKind': 'PushNotificationPayload',",
354 "'payloadVersion': 1,",
355 $
"'visual': {{ 'title': '{NotificationContractDeletedTitle}', 'body': '{NotificationContractDeletedBody}' }},",
356 $
"'action': {{ 'type': '{NotificationAction.OpenContract}', 'entityId': GetAttribute(E,'contractId'), 'correlationId': GetAttribute(E,'contractId') }},",
357 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Contracts}' }},",
358 "'delivery': { 'priority': 'High' },",
359 "'data': { 'contractId': GetAttribute(E,'contractId') }",
370 "E:=GetElement(Stanza,'contractProposal');",
371 $
"TitleText:='{NotificationContractProposalTitle}';",
372 $
"BodyText:='{NotificationContractProposalBody}';",
374 "'payloadKind': 'PushNotificationPayload',",
375 "'payloadVersion': 1,",
376 "'visual': { 'title': TitleText, 'body': BodyText },",
377 $
"'action': {{ 'type': '{NotificationAction.OpenContract}', 'entityId': GetAttribute(E,'contractId'), 'correlationId': GetAttribute(E,'contractId') }},",
378 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Contracts}' }},",
379 "'delivery': { 'priority': 'High' },",
380 "'data': { 'contractId': Num(GetAttribute(E,'contractId')), 'role': Num(GetAttribute(E,'role')) }",
391 "E:=GetElement(Stanza,'balance');",
392 $
"TitleText:='{NotificationBalanceUpdatedTitle}';",
393 $
"BodyText:='{NotificationBalanceUpdatedBody}';",
395 "'payloadKind': 'PushNotificationPayload',",
396 "'payloadVersion': 1,",
397 "'visual': { 'title': TitleText, 'body': BodyText },",
398 $
"'action': {{ 'type': '{NotificationAction.OpenBalance}', 'entityId': GetAttribute(E,'currency'), 'correlationId': GetAttribute(E,'currency') }},",
399 $
"'channel': {{ 'channelId': '{Constants.PushChannels.EDaler}' }},",
400 "'delivery': { 'priority': 'High' },",
401 "'data': { 'amount': Num(GetAttribute(E,'amount')), 'currency': GetAttribute(E,'currency'), 'timestamp': DateTime(GetAttribute(E,'timestamp')) }",
412 "E:=GetElement(Stanza,'tokenAdded');",
413 "E2:=GetElement(E,'token');",
414 $
"TitleText:='{NotificationTokenAddedTitle}';",
415 $
"BodyText:='{NotificationTokenAddedBody}';",
417 "'payloadKind': 'PushNotificationPayload',",
418 "'payloadVersion': 1,",
419 "'visual': { 'title': TitleText, 'body': BodyText },",
420 $
"'action': {{ 'type': '{NotificationAction.OpenToken}', 'entityId': GetAttribute(E2,'tokenId'), 'correlationId': GetAttribute(E2,'tokenId') }},",
421 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Tokens}' }},",
422 "'delivery': { 'priority': 'High' },",
423 "'data': { 'tokenId': GetAttribute(E2,'tokenId'), 'value': Num(GetAttribute(E2,'value')), 'currency': GetAttribute(E2,'currency') }",
434 "E:=GetElement(Stanza,'tokenRemoved');",
435 "E2:=GetElement(E,'token');",
436 $
"TitleText:='{NotificationTokenRemovedTitle}';",
437 $
"BodyText:='{NotificationTokenRemovedBody}';",
439 "'payloadKind': 'PushNotificationPayload',",
440 "'payloadVersion': 1,",
441 "'visual': { 'title': TitleText, 'body': BodyText },",
442 $
"'action': {{ 'type': '{NotificationAction.OpenToken}', 'entityId': GetAttribute(E2,'tokenId'), 'correlationId': GetAttribute(E2,'tokenId') }},",
443 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Tokens}' }},",
444 "'delivery': { 'priority': 'High' },",
445 "'data': { 'tokenId': GetAttribute(E2,'tokenId'), 'value': Num(GetAttribute(E2,'value')), 'currency': GetAttribute(E2,'currency') }",
456 "ToJid:=GetAttribute(Stanza,'to');",
457 "E:=GetElement(Stanza,'isFriend');",
458 "RemoteJid:=GetAttribute(E,'remoteJid');",
459 "FriendlyName:=RosterName(ToJid,RemoteJid);",
460 $
"TitleText:='{NotificationPresenceAccessTitle}';",
461 $
"BodyText:='{NotificationPresenceAccessBody}';",
463 "'payloadKind': 'PushNotificationPayload',",
464 "'payloadVersion': 1,",
465 "'visual': { 'title': Replace(TitleText,'{0}',FriendlyName), 'body': BodyText },",
466 $
"'action': {{ 'type': '{NotificationAction.OpenPresenceRequest}', 'entityId': RemoteJid }},",
467 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Provisioning}' }},",
468 "'delivery': { 'priority': 'High' },",
469 "'context': { 'toJid': ToJid, 'remoteJid': RemoteJid },",
470 "'data': { 'remoteJid': RemoteJid, 'jid': GetAttribute(E,'jid'), 'key': GetAttribute(E,'key'), 'q': 'isFriend' }",
481 "ToJid:=GetAttribute(Stanza,'to');",
482 "E:=GetElement(Stanza,'canRead');",
483 "RemoteJid:=GetAttribute(E,'remoteJid');",
484 "FriendlyName:=RosterName(ToJid,RemoteJid);",
485 $
"TitleText:='{NotificationReadAccessTitle}';",
486 $
"BodyText:='{NotificationReadAccessBody}';",
488 "'payloadKind': 'PushNotificationPayload',",
489 "'payloadVersion': 1,",
490 "'visual': { 'title': Replace(TitleText,'{0}',FriendlyName), 'body': BodyText },",
491 $
"'action': {{ 'type': '{NotificationAction.OpenPresenceRequest}', 'entityId': RemoteJid }},",
492 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Provisioning}' }},",
493 "'delivery': { 'priority': 'High' },",
494 "'context': { 'toJid': ToJid, 'remoteJid': RemoteJid },",
495 "'data': { 'remoteJid': RemoteJid, 'jid': GetAttribute(E,'jid'), 'key': GetAttribute(E,'key'), 'q': 'canRead' }",
506 "ToJid:=GetAttribute(Stanza,'to');",
507 "E:=GetElement(Stanza,'canControl');",
508 "RemoteJid:=GetAttribute(E,'remoteJid');",
509 "FriendlyName:=RosterName(ToJid,RemoteJid);",
510 $
"TitleText:='{NotificationControlAccessTitle}';",
511 $
"BodyText:='{NotificationControlAccessBody}';",
513 "'payloadKind': 'PushNotificationPayload',",
514 "'payloadVersion': 1,",
515 "'visual': { 'title': Replace(TitleText,'{0}',FriendlyName), 'body': BodyText },",
516 $
"'action': {{ 'type': '{NotificationAction.OpenPresenceRequest}', 'entityId': RemoteJid }},",
517 $
"'channel': {{ 'channelId': '{Constants.PushChannels.Provisioning}' }},",
518 "'delivery': { 'priority': 'High' },",
519 "'context': { 'toJid': ToJid, 'remoteJid': RemoteJid },",
520 "'data': { 'remoteJid': RemoteJid, 'jid': GetAttribute(E,'jid'), 'key': GetAttribute(E,'key'), 'q': 'canControl' }",
526 private static string ComputeHash(IEnumerable<PushRuleDefinition> rules)
528 StringBuilder builder =
new();
530 foreach (PushRuleDefinition rule
in rules)
532 builder.Append(rule.MessageType.ToString());
534 builder.Append(rule.LocalName);
536 builder.Append(rule.Namespace);
538 builder.Append(rule.Channel);
540 builder.Append(rule.MessageVariable);
542 builder.Append(rule.PatternScript);
544 builder.Append(rule.ContentScript);
545 builder.AppendLine();
548 byte[] bytes = Encoding.UTF8.GetBytes(builder.ToString());
549 byte[] hash = SHA256.HashData(bytes);
550 return Convert.ToHexString(hash);
553 private static string Script(params
string[] lines) =>
string.Join(
'\n', lines);
const string NamespaceEDaler
Namespace of eDaler component.
const string Provisioning
Provisioning channel
const string Petitions
Petitions channel
const string Identities
Identities channel
const string Messages
Messages channel
const string EDaler
eDaler channel
const string Tokens
Tokens channel
const string Contracts
Contracts channel
A set of never changing property constants and helpful values.
A strongly-typed resource class, for looking up localized strings, etc.
static string NotificationPetitionContractTitle
Looks up a localized string similar to Contract request from {0}.
static string NotificationIdentityRejectedBody
Looks up a localized string similar to Your identity was rejected..
static string NotificationPetitionSignatureBody
Looks up a localized string similar to A new signature request is waiting..
static string NotificationReadAccessBody
Looks up a localized string similar to Requested read access..
static string NotificationContractProposalTitle
Looks up a localized string similar to Contract proposal.
static string NotificationTokenRemovedBody
Looks up a localized string similar to Your wallet was updated..
static string NotificationReadAccessTitle
Looks up a localized string similar to Read access request from {0}.
static string NotificationIdentityRejectedTitle
Looks up a localized string similar to Identity status updated.
static string NotificationContractProposalBody
Looks up a localized string similar to A contract proposal is available..
static string NotificationIdentityCompromisedBody
Looks up a localized string similar to Your identity may be compromised..
static string NotificationTokenRemovedTitle
Looks up a localized string similar to Token removed.
static string NotificationIdentityObsoletedBody
Looks up a localized string similar to Your identity has been obsoleted..
static string NotificationBalanceUpdatedTitle
Looks up a localized string similar to Balance updated.
static string NotificationPetitionIdentityBody
Looks up a localized string similar to A new identity request is waiting..
static string NotificationIdentityApprovedBody
Looks up a localized string similar to Your identity was approved..
static string NotificationControlAccessBody
Looks up a localized string similar to Requested control access..
static string NotificationContractUpdatedTitle
Looks up a localized string similar to Contract updated.
static string NotificationPetitionIdentityTitle
Looks up a localized string similar to Identity request from {0}.
static string NotificationContractUpdatedBody
Looks up a localized string similar to A contract was updated..
static string NotificationContractSignedTitle
Looks up a localized string similar to Contract signed.
static string NotificationTokenAddedBody
Looks up a localized string similar to Your wallet was updated..
static string NotificationBalanceUpdatedBody
Looks up a localized string similar to Your balance was updated..
static string NotificationContractCreatedBody
Looks up a localized string similar to A new contract was created..
static string NotificationControlAccessTitle
Looks up a localized string similar to Control request from {0}.
static string NotificationIdentityApprovedTitle
Looks up a localized string similar to Identity status updated.
static string NotificationChatTitle
Looks up a localized string similar to {0}.
static string NotificationIdentityCompromisedTitle
Looks up a localized string similar to Identity status updated.
static string NotificationTokenAddedTitle
Looks up a localized string similar to Token added.
static string NotificationContractCreatedTitle
Looks up a localized string similar to Contract created.
static string NotificationChatBody
Looks up a localized string similar to Has sent you a message..
static string NotificationPresenceAccessBody
Looks up a localized string similar to Requested access to your identity..
static string NotificationPetitionSignatureTitle
Looks up a localized string similar to Signature request from {0}.
static string NotificationContractDeletedTitle
Looks up a localized string similar to Contract removed.
static string NotificationPetitionContractBody
Looks up a localized string similar to A new contract request is waiting..
static string NotificationPresenceAccessTitle
Looks up a localized string similar to Access request from {0}.
static string NotificationIdentityObsoletedTitle
Looks up a localized string similar to Identity status updated.
static string NotificationContractDeletedBody
Looks up a localized string similar to A contract was removed..
static string NotificationContractSignedBody
Looks up a localized string similar to A contract was signed..
Describes a push notification rule to provision in the XMPP broker.
string Channel
Push channel identifier.
string PatternScript
Optional pattern script to filter matching stanzas.
PushRuleDefinition(MessageType messageType, string localName, string @namespace, string channel, string messageVariable, string patternScript, string contentScript)
Initializes a new instance of the PushRuleDefinition class.
string Namespace
Namespace of the stanza element.
string LocalName
Local name of the stanza element.
string ContentScript
Script that produces the transport-agnostic push payload forwarded to the broker.
string MessageVariable
Variable name for the stanza passed into the rule.
Provides the set of push rules to provision.
static string RuleSetHash
Gets a hash representing the current rule set.
static IReadOnlyList< PushRuleDefinition > All
Gets all rule Definitions.
Base class that references services in the app.
static IReportingStringLocalizer Localizer
Localization service
const string NamespaceNeuroFeatures
Namespace for Neuro-Features.
Helps with common JSON-related tasks.
static string Encode(string s)
Encodes a string for inclusion in JSON.
Adds support for legal identities, smart contracts and signatures to an XMPP client.
const string NamespaceSmartContractsCurrent
Current namespce for smart contracts.
const string NamespaceLegalIdentitiesCurrent
Current namespace for legal identities.
Implements an XMPP provisioning client interface.
const string NamespaceProvisioningOwnerCurrent
Current namespace for provisioning by owners.
MessageType
Type of message received.