2using System.Collections.Generic;
5using System.Threading.Tasks;
31 private static readonly Dictionary<CaseInsensitiveString, Dictionary<string, Dictionary<string, string>>> functionsPerTabIdPerFqnPerBareJid =
new Dictionary<CaseInsensitiveString, Dictionary<string, Dictionary<string, string>>>();
33 private readonly Dictionary<CaseInsensitiveString, Account> accounts =
new Dictionary<CaseInsensitiveString, Account>();
34 private readonly Dictionary<CaseInsensitiveString, Dictionary<CaseInsensitiveString, RosterItem>> rosters =
new Dictionary<CaseInsensitiveString, Dictionary<CaseInsensitiveString, RosterItem>>();
35 private readonly Dictionary<CaseInsensitiveString, Dictionary<CaseInsensitiveString, Block>> blocks =
new Dictionary<CaseInsensitiveString, Dictionary<CaseInsensitiveString, Block>>();
50 if (this.server is
null)
52 else if (this.server != value)
53 throw new InvalidOperationException(
"Not allowed to change server reference in runtime.");
57 public string Domain => this.server.Domain;
67 internal async Task<ApiKey> GetApiKey(
string ApiKey)
79 return (await this.GetApiKey(
ApiKey))?.Secret;
98 this.accounts[Account.UserName] = Account;
121 ApiKey ApiKeyObject =
null;
124 return new KeyValuePair<Networking.XMPP.Server.IAccount,
string[]>(
null, await GetAlternativeAccountNames(UserName));
130 return new KeyValuePair<Networking.XMPP.Server.IAccount,
string[]>(
null, await GetAlternativeAccountNames(UserName));
137 if (File.Exists(s) || Directory.Exists(s))
138 return new KeyValuePair<Networking.XMPP.Server.IAccount,
string[]>(
null, await GetAlternativeAccountNames(UserName));
145 if (
string.IsNullOrEmpty(
ApiKey))
153 EMailVerified =
null,
155 PhoneNrVerified =
null,
156 Created = DateTime.Now
165 if (Key.NrCreated - Key.NrDeleted >= Key.MaxAccounts)
166 return new KeyValuePair<Networking.XMPP.Server.IAccount,
string[]>(
null,
null);
176 EMailVerified =
null,
178 PhoneNrVerified =
null,
179 Created = DateTime.Now
194 return new KeyValuePair<Networking.XMPP.Server.IAccount,
string[]>(
Account,
null);
197 internal static async Task<string[]> GetAlternativeAccountNames(
string UserName)
199 List<string> Suggestions =
new List<string>();
203 while (Suggestions.Count < 3 && NrDigits < 9)
205 string AlternativeName = UserName +
Gateway.
NextInteger(Max).ToString(
"D" + NrDigits.ToString());
210 if (!(AlternativeAccount is
null))
232 if (File.Exists(s) || Directory.Exists(s))
244 Suggestions.Add(AlternativeName);
249 return Suggestions.ToArray();
252 internal static async Task AccountCreated(Account Account, ApiKey ApiKeyObject,
258 new KeyValuePair<string, object>(
"ApiKey", Account.ApiKey),
259 new KeyValuePair<string, object>(
"Created", Account.Created),
260 new KeyValuePair<string, object>(
"EMail", Account.EMail?.Value),
261 new KeyValuePair<string, object>(
"PhoneNr", Account.PhoneNr?.Value),
262 new KeyValuePair<string, object>(
"Enabled", Account.Enabled),
263 new KeyValuePair<string, object>(
"ObjectId", Account.ObjectId),
264 new KeyValuePair<string, object>(
"RemoteEndpoint",
RemoteEndpoint));
266 StringBuilder sb =
new StringBuilder();
267 string WhoIsInfo =
string.Empty;
269 sb.Append(
"Account created.");
274 StringBuilder Markdown =
new StringBuilder();
276 DateTime Now = DateTime.Now;
278 Markdown.AppendLine(
"XMPP Account created:");
279 Markdown.AppendLine();
280 Markdown.AppendLine(
"| Account Information ||");
281 Markdown.AppendLine(
"|:-----|:------|");
282 Markdown.Append(
"| User Name: | [");
283 Markdown.Append(UserNameEncoded);
284 Markdown.Append(
"](");
285 Markdown.Append(
Gateway.
GetUrl(
"/Account.md?UserName=" + UserNameEncoded));
286 Markdown.AppendLine(
") |");
287 Markdown.Append(
"| JID: | [");
288 Markdown.Append(UserNameEncoded);
289 Markdown.Append(
'@');
291 Markdown.Append(
"](xmpp:");
292 Markdown.Append(UserNameEncoded);
293 Markdown.Append(
'@');
295 Markdown.Append(
")");
296 Markdown.AppendLine(
" |");
300 Markdown.Append(
"| e-Mail: | <mailto:");
301 Markdown.Append(Account.EMail.Value);
302 Markdown.AppendLine(
"> |");
307 Markdown.Append(
"| Phone Nr: | <tel:");
308 Markdown.Append(Account.PhoneNr.Value);
309 Markdown.AppendLine(
"> |");
314 Markdown.Append(
"| Date | ");
316 Markdown.AppendLine(
" |");
317 Markdown.Append(
"| Time | ");
319 Markdown.AppendLine(
" |");
321 if (!(ApiKeyObject is
null))
323 Markdown.AppendLine();
324 Markdown.AppendLine(
"| API Key information ||");
325 Markdown.AppendLine(
"|:-----|:------|");
326 Markdown.Append(
"| API Key: | [");
327 Markdown.Append(ApiKeyObject.Key);
328 Markdown.Append(
"](");
329 Markdown.Append(
Gateway.
GetUrl(
"/ApiKey.md?Key=" + ApiKeyObject.Key));
330 Markdown.AppendLine(
") |");
331 Markdown.Append(
"| Owner: | ");
333 Markdown.AppendLine(
" |");
334 Markdown.Append(
"| e-Mail: | <");
335 Markdown.Append(ApiKeyObject.EMail.Value);
336 Markdown.AppendLine(
"> |");
337 Markdown.Append(
"| Accounts created: | ");
338 Markdown.Append(ApiKeyObject.NrCreated.ToString());
339 Markdown.AppendLine(
" |");
340 Markdown.Append(
"| Accounts deleted: | ");
341 Markdown.Append(ApiKeyObject.NrDeleted.ToString());
342 Markdown.AppendLine(
" |");
343 Markdown.Append(
"| Accounts left: | ");
344 Markdown.Append((ApiKeyObject.MaxAccounts - ApiKeyObject.NrCreated + ApiKeyObject.NrDeleted).ToString());
345 Markdown.AppendLine(
" |");
348 if (!
string.IsNullOrEmpty(WhoIsInfo))
350 Markdown.AppendLine();
351 Markdown.AppendLine();
352 Markdown.AppendLine(
"WHOIS Information:");
353 Markdown.AppendLine();
354 Markdown.AppendLine(
"```");
355 Markdown.AppendLine(WhoIsInfo);
356 Markdown.AppendLine(
"```");
370 ApiKey ApiKeyObject =
null;
382 this.accounts.Remove(UserName);
403 new KeyValuePair<string, object>(
"LastLogin",
Login.LastLogin),
405 new KeyValuePair<string, object>(
"RemoteEndpoint",
Login.RemoteEndpoint));
411 StringBuilder Markdown =
new StringBuilder();
413 DateTime Now = DateTime.Now;
415 Markdown.AppendLine(
"XMPP Account deleted:");
416 Markdown.AppendLine();
417 Markdown.AppendLine(
"| Account Information ||");
418 Markdown.AppendLine(
"|:-----|:------|");
419 Markdown.Append(
"| User Name: | ");
420 Markdown.Append(UserNameEncoded);
421 Markdown.AppendLine(
" |");
422 Markdown.Append(
"| JID: | ");
423 Markdown.Append(UserNameEncoded);
424 Markdown.Append(
'@');
425 Markdown.Append(this.server.Domain);
426 Markdown.AppendLine(
" |");
430 Markdown.Append(
"| e-Mail: | <mailto:");
432 Markdown.AppendLine(
"> |");
437 Markdown.Append(
"| Phone Nr: | <tel:");
439 Markdown.AppendLine(
"> |");
444 Markdown.Append(
"| Date | ");
446 Markdown.AppendLine(
" |");
447 Markdown.Append(
"| Time | ");
449 Markdown.AppendLine(
" |");
451 if (!(ApiKeyObject is
null))
453 Markdown.AppendLine();
454 Markdown.AppendLine(
"| API Key information ||");
455 Markdown.AppendLine(
"|:-----|:------|");
456 Markdown.Append(
"| API Key: | [");
458 Markdown.Append(
"](");
460 Markdown.AppendLine(
") |");
461 Markdown.Append(
"| Owner: | ");
463 Markdown.AppendLine(
" |");
464 Markdown.Append(
"| e-Mail: | <");
465 Markdown.Append(ApiKeyObject.EMail);
466 Markdown.AppendLine(
"> |");
467 Markdown.Append(
"| Accounts created: | ");
468 Markdown.Append(ApiKeyObject.NrCreated.ToString());
469 Markdown.AppendLine(
" |");
470 Markdown.Append(
"| Accounts deleted: | ");
471 Markdown.Append(ApiKeyObject.NrDeleted.ToString());
472 Markdown.AppendLine(
" |");
473 Markdown.Append(
"| Accounts left: | ");
474 Markdown.Append((ApiKeyObject.MaxAccounts - ApiKeyObject.NrCreated + ApiKeyObject.NrDeleted).ToString());
475 Markdown.AppendLine(
" |");
498 Account.Password = Password;
538 Dictionary<CaseInsensitiveString, RosterItem> Roster;
542 if (this.rosters.TryGetValue(UserName, out Roster))
543 return this.ToArrayLocked(Roster);
546 if (await this.GetAccountEx(UserName) is
null)
549 Roster =
new Dictionary<CaseInsensitiveString, RosterItem>();
553 if (Roster.ContainsKey(Item.
BareJid))
561 this.rosters[UserName] = Roster;
562 return this.ToArrayLocked(Roster);
566 private IRosterItem[] ToArrayLocked(Dictionary<CaseInsensitiveString, RosterItem> Roster)
571 int c = Roster.Count;
590 if (this.rosters.TryGetValue(UserName, out Dictionary<CaseInsensitiveString, RosterItem> Roster) &&
597 if (await this.
GetRoster(UserName) is
null)
602 if (this.rosters.TryGetValue(UserName, out Dictionary<CaseInsensitiveString, RosterItem> Roster) &&
625 Dictionary<CaseInsensitiveString, RosterItem> Roster;
631 if (this.rosters.TryGetValue(UserName, out Roster))
633 if (!Roster.TryGetValue(Jid, out Item))
645 if (await this.
GetRoster(UserName) is
null)
650 if (this.rosters.TryGetValue(UserName, out Roster))
652 if (!Roster.TryGetValue(Jid, out Item))
663 Item.Groups = Groups;
674 new KeyValuePair<string, object>(
"Name", Item.
Name),
675 new KeyValuePair<string, object>(
"ObjectId", Item.ObjectId),
677 new KeyValuePair<string, object>(
"Subscription", Item.
Subscription),
678 new KeyValuePair<string, object>(
"NrGroups", Item.
Groups is
null ? 0 : Item.
Groups.Length));
698 new KeyValuePair<string, object>(
"Name", Item.
Name),
699 new KeyValuePair<string, object>(
"ObjectId", Item.ObjectId),
701 new KeyValuePair<string, object>(
"Subscription", Item.
Subscription),
702 new KeyValuePair<string, object>(
"NrGroups", Item.
Groups is
null ? 0 : Item.
Groups.Length));
718 Dictionary<CaseInsensitiveString, RosterItem> Roster;
723 if (this.rosters.TryGetValue(UserName, out Roster))
725 if (Roster.TryGetValue(Jid, out Item))
734 if (await this.
GetRoster(UserName) is
null)
739 if (this.rosters.TryGetValue(UserName, out Roster))
741 if (Roster.TryGetValue(Jid, out Item))
752 new KeyValuePair<string, object>(
"Name", Item.
Name),
753 new KeyValuePair<string, object>(
"ObjectId", Item.ObjectId),
755 new KeyValuePair<string, object>(
"Subscription", Item.
Subscription),
756 new KeyValuePair<string, object>(
"NrGroups", Item.
Groups is
null ? 0 : Item.
Groups.Length));
776 Dictionary<CaseInsensitiveString, Block> Blocks;
783 if (this.blocks.TryGetValue(UserName, out Blocks))
784 Found = Blocks.TryGetValue(BareJid, out Item);
796 if (this.blocks.TryGetValue(UserName, out Blocks))
797 Found = Blocks.TryGetValue(BareJid, out Item);
803 if (Found && !(Item is
null))
805 Item.Reason = Reason;
807 Item.Language = TextLanguage;
812 new KeyValuePair<string, object>(
"ObjectId", Item.ObjectId),
813 new KeyValuePair<string, object>(
"Reason", Item.Reason),
814 new KeyValuePair<string, object>(
"Text", Item.Text),
815 new KeyValuePair<string, object>(
"Language", Item.Language));
828 Language = TextLanguage
831 Blocks[BareJid] = Item;
837 new KeyValuePair<string, object>(
"ObjectId", Item.ObjectId),
838 new KeyValuePair<string, object>(
"Reason", Item.Reason),
839 new KeyValuePair<string, object>(
"Text", Item.Text),
840 new KeyValuePair<string, object>(
"Language", Item.Language));
853 Dictionary<CaseInsensitiveString, Block> Blocks;
858 if (this.blocks.TryGetValue(UserName, out Blocks))
860 if (Blocks.TryGetValue(BareJid, out Item) && !(Item is
null))
861 Blocks[BareJid] =
null;
874 if (this.blocks.TryGetValue(UserName, out Blocks))
876 if (Blocks.TryGetValue(BareJid, out Item) && !(Item is
null))
877 Blocks[BareJid] =
null;
887 new KeyValuePair<string, object>(
"ObjectId", Item.ObjectId),
888 new KeyValuePair<string, object>(
"Reason", Item.Reason),
889 new KeyValuePair<string, object>(
"Text", Item.Text),
890 new KeyValuePair<string, object>(
"Language", Item.Language));
902 Dictionary<CaseInsensitiveString, Block> Blocks;
906 if (this.blocks.TryGetValue(UserName, out Blocks))
907 this.blocks.Remove(UserName);
917 if (this.blocks.TryGetValue(UserName, out Blocks))
919 if (this.blocks.TryGetValue(UserName, out Blocks))
920 this.blocks.Remove(UserName);
927 foreach (
Block Item
in Blocks.Values)
932 new KeyValuePair<string, object>(
"ObjectId", Item.ObjectId),
933 new KeyValuePair<string, object>(
"Reason", Item.Reason),
934 new KeyValuePair<string, object>(
"Text", Item.Text),
935 new KeyValuePair<string, object>(
"Language", Item.Language));
948 Dictionary<CaseInsensitiveString, Block> Blocks;
952 if (this.blocks.TryGetValue(UserName, out Blocks))
953 return this.ToArrayLocked(Blocks);
956 if (await this.GetAccountEx(UserName) is
null)
959 Blocks =
new Dictionary<CaseInsensitiveString, Block>();
962 Blocks[Item.Jid] = Item;
966 this.blocks[UserName] = Blocks;
967 return this.ToArrayLocked(Blocks);
973 List<CaseInsensitiveString> Result =
new List<CaseInsensitiveString>();
975 foreach (
Block Item
in Blocks.Values)
978 Result.Add(Item.Jid);
981 return Result.ToArray();
988 if (this.blocks.TryGetValue(UserName, out Dictionary<CaseInsensitiveString, Block> Blocks) &&
989 Blocks.TryGetValue(Jid, out Block Block))
1000 if (this.blocks.TryGetValue(UserName, out Dictionary<CaseInsensitiveString, Block> Blocks))
1002 if (Blocks.TryGetValue(Jid, out Block Block))
1020 int i = ToBareJid.
IndexOf(
'@');
1025 if (!this.server.IsServerDomain(
Domain,
true))
1029 Block Block = await this.GetBlock(ToUserName, FromBareJid);
1031 return !(
Block is
null);
1046 return new Tuple<string, byte[]>(
Avatar.ContentType,
Avatar.Data);
1066 Avatar.ContentType = ContentType;
1072 new KeyValuePair<string, object>(
"ObjectId",
Avatar.ObjectId),
1073 new KeyValuePair<string, object>(
"ContentType",
Avatar.ContentType),
1074 new KeyValuePair<string, object>(
"Bytes",
Avatar.Data.Length));
1081 UserName = UserName,
1082 ContentType = ContentType,
1089 new KeyValuePair<string, object>(
"ObjectId", Avatar2.ObjectId),
1090 new KeyValuePair<string, object>(
"ContentType", Avatar2.ContentType),
1091 new KeyValuePair<string, object>(
"Bytes", Avatar2.Data.Length));
1108 return VCard.VCardXml;
1127 VCard2.VCardXml =
VCard;
1131 new KeyValuePair<string, object>(
"ObjectId", VCard2.ObjectId));
1138 UserName = UserName,
1145 new KeyValuePair<string, object>(
"ObjectId", VCard3.ObjectId));
1173 if (
string.IsNullOrEmpty(s))
1177 s = Convert.ToBase64String(Data, Base64FormattingOptions.None);
1182 return Convert.FromBase64String(s);
1187 #region Offline messages
1214 bool Unregistering =
string.IsNullOrEmpty(
Function);
1216 lock (functionsPerTabIdPerFqnPerBareJid)
1218 if (!functionsPerTabIdPerFqnPerBareJid.TryGetValue(BareJid, out Dictionary<
string, Dictionary<string, string>> FunctionsPerTabIdPerFqn))
1223 FunctionsPerTabIdPerFqn =
new Dictionary<string, Dictionary<string, string>>();
1224 functionsPerTabIdPerFqnPerBareJid[BareJid] = FunctionsPerTabIdPerFqn;
1227 if (!FunctionsPerTabIdPerFqn.TryGetValue(Fqn, out Dictionary<string, string> FunctionsPerTabId))
1232 FunctionsPerTabId =
new Dictionary<string, string>();
1233 FunctionsPerTabIdPerFqn[Fqn] = FunctionsPerTabId;
1238 if (!FunctionsPerTabId.Remove(TabId))
1241 if (FunctionsPerTabId.Count > 0)
1244 if (!FunctionsPerTabIdPerFqn.Remove(Fqn))
1247 if (FunctionsPerTabIdPerFqn.Count > 0)
1250 return functionsPerTabIdPerFqnPerBareJid.Remove(BareJid);
1252 else if (FunctionsPerTabId.TryGetValue(TabId, out
string s) && s ==
Function)
1256 FunctionsPerTabId[TabId] =
Function;
1264 StringBuilder sb =
new StringBuilder();
1268 sb.Append(LocalName);
1272 return sb.ToString();
1298 string Type,
string XmlContent, XmlElement StanzaElement)
1300 lock (functionsPerTabIdPerFqnPerBareJid)
1302 XmlElement FirstContent =
null;
1304 if (!functionsPerTabIdPerFqnPerBareJid.TryGetValue(BareJid, out Dictionary<
string, Dictionary<string, string>> FunctionsPerTabIdPerFqn))
1307 if (StanzaElement is
null)
1311 StringBuilder Xml =
new StringBuilder();
1313 Xml.Append(
"<message xmlns=\"");
1316 Xml.Append(XmlContent);
1317 Xml.Append(
"</message>");
1319 XmlDocument Doc =
new XmlDocument();
1320 Doc.LoadXml(XmlContent);
1321 StanzaElement = Doc.DocumentElement;
1329 Dictionary<string, string> FunctionsPerTabId;
1330 List<ClientPushRecord> Result =
null;
1333 foreach (XmlNode N
in StanzaElement.ChildNodes)
1335 if (N is XmlElement E)
1337 if (FirstContent is
null)
1340 Key = EventHandlerKey(Type, E.LocalName, E.NamespaceURI);
1341 if (FunctionsPerTabIdPerFqn.TryGetValue(Key, out FunctionsPerTabId))
1344 Result =
new List<ClientPushRecord>();
1346 foreach (KeyValuePair<string, string> P
in FunctionsPerTabId)
1348 Result.Add(
new ClientPushRecord()
1351 LocalName = E.LocalName,
1360 Key = EventHandlerKey(Type,
string.Empty, E.NamespaceURI);
1361 if (FunctionsPerTabIdPerFqn.TryGetValue(Key, out FunctionsPerTabId))
1364 Result =
new List<ClientPushRecord>();
1366 foreach (KeyValuePair<string, string> P
in FunctionsPerTabId)
1368 Result.Add(
new ClientPushRecord()
1371 LocalName =
string.Empty,
1380 Key = EventHandlerKey(
string.Empty,
string.Empty, E.NamespaceURI);
1381 if (FunctionsPerTabIdPerFqn.TryGetValue(Key, out FunctionsPerTabId))
1384 Result =
new List<ClientPushRecord>();
1386 foreach (KeyValuePair<string, string> P
in FunctionsPerTabId)
1388 Result.Add(
new ClientPushRecord()
1390 Type =
string.Empty,
1391 LocalName =
string.Empty,
1402 if (!(FirstContent is
null))
1404 Key = EventHandlerKey(
string.Empty,
string.Empty,
string.Empty);
1405 if (FunctionsPerTabIdPerFqn.TryGetValue(Key, out FunctionsPerTabId))
1408 Result =
new List<ClientPushRecord>();
1410 foreach (KeyValuePair<string, string> P
in FunctionsPerTabId)
1412 Result.Add(
new ClientPushRecord()
1414 Type =
string.Empty,
1415 LocalName =
string.Empty,
1425 return Result?.ToArray();
1429 internal class ClientPushRecord
1432 public string LocalName;
1435 public string TabId;
1436 public XmlElement Data;
1487 ClientPushRecord[] ClientPushRecords = GetEventTabs(BareJid, Type, ContentXml,
null);
1489 if (!(ClientPushRecords is
null) && await PushMessageToClients(BareJid, ClientPushRecords))
1499 Language = Language,
1500 ContentXml = ContentXml,
1501 Timestamp = DateTime.UtcNow
1507 if (!(Token is
null))
1510 if (!(Rule is
null))
1512 XmlElement StanzaElement = this.RecreateStanza(ContentXml);
1513 if (!(StanzaElement is
null))
1516 else if (!
string.IsNullOrEmpty(ContentXml))
1518 XmlElement StanzaElement = this.RecreateStanza(ContentXml);
1519 if (!(StanzaElement is
null))
1528 ClientPushRecord[] ClientPushRecords)
1530 if (ClientPushRecords is
null)
1535 foreach (ClientPushRecord Rec
in ClientPushRecords)
1540 UnregisterEventsTab(BareJid, Rec.Type, Rec.LocalName, Rec.Namespace, Rec.TabId);
1546 private XmlElement RecreateStanza(
string ContentXml)
1548 if (
string.IsNullOrEmpty(ContentXml))
1553 XmlDocument Doc =
new XmlDocument();
1554 Doc.LoadXml(
"<message xmlns='jabber:client'>" + ContentXml +
"</message>");
1555 return Doc.DocumentElement;
1557 catch (Exception ex)
1564 private async Task ProcessOfflineStanza(
CaseInsensitiveString BareJid,
string Type, XmlElement StanzaElement,
1567 foreach (XmlNode N
in StanzaElement.ChildNodes)
1569 if (N is XmlElement E)
1572 if (!(Rule is
null))
1574 await this.ProcessOfflineRule(Rule, StanzaElement, Token, Type, Id, To, From);
1584 return !(Node is Script.Persistence.Functions.XPath);
1588 string Type,
string Id,
string To,
string From)
1592 if (!
string.IsNullOrEmpty(Type) && !StanzaElement.HasAttribute(
"type"))
1593 StanzaElement.SetAttribute(
"type", Type);
1595 if (!
string.IsNullOrEmpty(Id) && !StanzaElement.HasAttribute(
"id"))
1596 StanzaElement.SetAttribute(
"id", Id);
1598 if (!
string.IsNullOrEmpty(To) && !StanzaElement.HasAttribute(
"to"))
1599 StanzaElement.SetAttribute(
"to", To);
1601 if (!
string.IsNullOrEmpty(From) && !StanzaElement.HasAttribute(
"from"))
1602 StanzaElement.SetAttribute(
"from", From);
1607 bool HasXPath = !((ContentExpression?.
ForAll(this.NoXPath,
null,
SearchMethod.TreeOrder) ??
true) &&
1608 (PatternMatchingExpression?.ForAll(this.NoXPath,
null,
SearchMethod.TreeOrder) ??
true));
1613 if (!(PatternMatchingExpression is
null))
1615 Dictionary<string, IElement> AlreadyFound =
new Dictionary<string, IElement>();
1620 foreach (KeyValuePair<string, IElement> P
in AlreadyFound)
1626 if (ContentExpression is
null)
1627 Content = StanzaElement;
1633 await h(Token, Content);
1637 catch (Exception ex)
1663 if (!(ClientPushRecords is
null) && await PushMessageToClients(BareJid, ClientPushRecords))
1673 Language = Language,
1675 Timestamp = DateTime.UtcNow
1681 if (!(Token is
null))
1684 if (!(Rule is
null))
1715 return await this.GetAccountEx(UserName);
1725 return await this.GetAccountEx(UserName);
1734 lock (this.accounts)
1736 this.accounts.Remove(UserName);
1739 return Task.CompletedTask;
Helps with common JSON-related tasks.
static string Encode(string s)
Encodes a string for inclusion in JSON.
Contains a markdown document. This markdown document class supports original markdown,...
static string Encode(string s)
Encodes all special characters in a string so that it can be included in a markdown document without ...
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
static void Informational(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an informational event.
The ClientEvents class allows applications to push information asynchronously to web clients connecte...
static Task< int > PushEvent(string[] TabIDs, string Type, object Data)
Puses an event to a set of Tabs, given their Tab IDs.
Static class managing the runtime environment of the IoT Gateway.
static LoginAuditor LoginAuditor
Current Login Auditor. Should be used by modules accepting user logins, to protect the system from un...
static byte[] NextBytes(int NrBytes)
Generates an array of random bytes.
static Task SendNotification(Graph Graph)
Sends a graph as a notification message to configured notification recipients.
static string GetUrl(string LocalResource)
Gets a URL for a resource.
static int NextInteger(int Max)
Returns a non-negative random integer that is less than the specified maximum.
static string RootFolder
Web root folder.
Authentication done by the LOGIN authentication mechanism. https://tools.ietf.org/html/draft-murchiso...
Abstract base class for XMPP client connections
const string C2SNamespace
jabber:client
Push Notification settings.
Expression PatternMatchingExpression
Parsed pattern-matching expression
Expression ContentExpression
Parsed content expression
string MessageVariable
Variable to put the Message XML in, before patternmatching or content script is executed.
Push Notification settings.
Contains information about a stanza.
string Content
Literal XML content.
XmlElement StanzaElement
Stanza element.
bool HasContent
If the stanza has content.
Contains information about one XMPP address.
CaseInsensitiveString Address
XMPP Address
CaseInsensitiveString BareJid
Bare JID
static readonly XmppAddress Empty
Empty address.
CaseInsensitiveString Account
Account
static byte[] GetRandomNumbers(int NrBytes)
Generates a set of random numbers.
static async Task< PushNotificationToken > TryGetPushNotificationToken(CaseInsensitiveString BareJid)
Tries to get a push notification token for a client, if one exists.
static async Task< PushNotificationRule > TryGetPushNotificationRule(CaseInsensitiveString BareJid, string MessageType, string LocalName, string Namespace)
Tries to get a push notification token for a client, if one exists.
Represents a case-insensitive string.
string Value
String-representation of the case-insensitive string. (Representation is case sensitive....
static readonly CaseInsensitiveString Empty
Empty case-insensitive string
int IndexOf(CaseInsensitiveString value, StringComparison comparisonType)
Reports the zero-based index of the first occurrence of the specified string in the current System....
static bool IsNullOrEmpty(CaseInsensitiveString value)
Indicates whether the specified string is null or an CaseInsensitiveString.Empty string.
CaseInsensitiveString Substring(int startIndex, int length)
Retrieves a substring from this instance. The substring starts at a specified character position and ...
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static Task< IEnumerable< object > > FindDelete(string Collection, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
static async Task Update(object Object)
Updates an object in the database.
static async Task Delete(object Object)
Deletes an object in the database.
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
This filter selects objects that have a named field equal to a given value.
This filter selects objects that have a named field lesser or equal to a given value.
Static class managing persistent settings.
static async Task< string > GetAsync(string Key, string DefaultValue)
Gets a string-valued setting.
static async Task< bool > SetAsync(string Key, string Value)
Sets a string-valued setting.
Class managing a script expression.
ScriptNode Root
Root script node.
async Task< object > EvaluateAsync(Variables Variables)
Evaluates the expression, using the variables provided in the Variables collection....
bool ForAll(ScriptNodeEventHandler Callback, object State, bool DepthFirst)
Calls the callback method for all script nodes defined for the expression.
Base class for all funcions.
Base class for all nodes in a parsed script tree.
virtual PatternMatchResult PatternMatch(IElement CheckAgainst, Dictionary< string, IElement > AlreadyFound)
Performs a pattern match operation.
Class that monitors login events, and help applications determine malicious intent....
static async Task< string > AppendWhoIsInfo(StringBuilder Markdown, string RemoteEndpoint)
Appends WHOIS information to a Markdown document.
static async Task< KeyValuePair< string, object >[]> Annotate(string RemoteEndpoint, params KeyValuePair< string, object >[] Tags)
Annotates a remote endpoint.
Login state information relating to a remote endpoint
Contains information about a broker account.
CaseInsensitiveString EMail
E-mail address associated with account.
CaseInsensitiveString UserName
User Name of account
bool Enabled
If account is enabled
async Task< AccountLogin > GetAccountLogin()
Gets the object with the associated account login status information.
string Password
Password of account
CaseInsensitiveString PhoneNr
Phone number associated with account.
async Task LoggedIn(string RemoteEndpoint)
Registers a log-in event on the account.
DateTime Created
When account was created associated with account holder.
string ApiKey
Reference to API Key used to create object.
async Task< bool > ClearBlocks(CaseInsensitiveString UserName)
Remove all blocks for an account.
Task AccountUpdated(CaseInsensitiveString UserName)
Called when account has been updated.
async Task< bool > ChangePassword(CaseInsensitiveString UserName, string Password)
Changes the password of an account.
async Task< bool > SetAvatar(CaseInsensitiveString UserName, string ContentType, byte[] Data)
Sets the Avatar of an account.
async Task< byte[]> GetDialbackSecret()
Gets the Dialback secret, as defined in XEP-0185.
Task< bool > IsPermitted(CaseInsensitiveString BareJid, string Setting)
Checks if a feature is permitted for a Bare JID.
async Task< int > DeleteOfflineMessages(DateTime OlderThan)
Deletes offline messages that are older than a specific timestamp.
async Task< IRosterItem > GetRosterItem(CaseInsensitiveString UserName, CaseInsensitiveString Jid)
Gets a roster item for an account.
async Task< bool > AddBlock(CaseInsensitiveString UserName, CaseInsensitiveString BareJid, BlockingReason Reason, string Text, string TextLanguage)
Blocks an account.
async Task< int > DeleteOfflineMessages(CaseInsensitiveString ToUserName)
Deletes offline messages for a given account.
async void AccountLogin(CaseInsensitiveString UserName, string RemoteEndpoint)
Successful login to account registered.
async Task< IEnumerable< CaseInsensitiveString > > GetBlockList(CaseInsensitiveString UserName)
Gets the entire block list for an account.
async Task< string > GetVCard(CaseInsensitiveString UserName)
Gets the vCard of an account.
async Task< IRosterItem > SetRosterItem(CaseInsensitiveString UserName, CaseInsensitiveString Jid, string Name, SubscriptionStatus? Subscription, bool? PendingSubscription, string[] Groups)
Sets a roster item in a users roster.
PushNotificationEventHandler OnPushNotification
Event raised when a push notification is performed.
string Domain
Current domain.
async Task< bool > StoreOfflineMessage(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza)
Tries to save an offline message.
async Task DeleteOfflineMessages(IEnumerable< IOfflineMessage > Messages)
Deletes offline messages.
async Task< KeyValuePair< Networking.XMPP.Server.IAccount, string[]> > CreateAccount(string ApiKey, CaseInsensitiveString UserName, string Password, CaseInsensitiveString EMail, CaseInsensitiveString PhoneNr, string RemoteEndpoint)
Creates an account.
async Task< bool > Unblock(CaseInsensitiveString UserName, CaseInsensitiveString BareJid)
Unblocks an account.
async Task< bool > StoreOfflineMessage(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
Tries to save an offline message.
XmppServer Server
Current XMPP Server.
async Task< IEnumerable< IRosterItem > > GetRoster(CaseInsensitiveString UserName)
Gets the roster of an account.
async Task< bool > DeleteAccount(CaseInsensitiveString UserName, string RemoteEndpoint)
Deletes an account.
async Task< IEnumerable< IOfflineMessage > > GetOfflineMessages(CaseInsensitiveString ToUserName, int Max)
Gets the oldest offline messages stored for a given bare JID, up to a maximum count.
async Task< Tuple< string, byte[]> > GetAvatar(CaseInsensitiveString UserName)
Gets the Avatar of an account.
async Task< bool > SetVCard(CaseInsensitiveString UserName, string VCard)
Sets the vCard of an account.
async Task< bool > IsBlocked(CaseInsensitiveString FromBareJid, CaseInsensitiveString ToBareJid)
Checks if a sender is blocked by a receiver.
byte[] GetRandomNumbers(int NrBytes)
Generates a set of random numbers.
async Task< string > GetApiKeySecret(string ApiKey)
Gets the secret for a given API key.
async Task< bool > RemoveRosterItem(CaseInsensitiveString UserName, CaseInsensitiveString Jid)
Removes a roster item.
LoginAuditor Auditor
Login auditor.
SubscriptionStatus Subscription
Subscription status.
CaseInsensitiveString BareJid
Bare JID.
bool PendingSubscription
If a presence subscription awaits.
string[] Groups
Groups assigned to roster item.
string Name
Name of roster item.
async Task< PubSubNode > GetNodeAsync(CaseInsensitiveString Service, CaseInsensitiveString NodeName, NodeAccessModel? AutoCreateAccess, XmppAddress From, CaseInsensitiveString Domain)
Gets a pubsub node.
Defines a node on which items can be published.
Defines a node subscription.
Provides the user configuration options regarding use of Push Notification to reach offline clients.
Service Module hosting the XMPP broker and its components.
static async Task AppendRemoteEndpointToTable(StringBuilder Markdown, string RemoteEndpoint)
Appends annotated information about a remote endpoint to a Markdown table.
Interface for XMPP Server persistence layers. The persistence layer should implement caching.
Task< IAccount > GetAccount(CaseInsensitiveString UserName)
Method to call to fetch account information.
Interface for roster items.
Interface for XMPP Server persistence layers. The persistence layer should implement caching.
new Task< IAccount > GetAccount(CaseInsensitiveString UserName)
Method to call to fetch account information.
SubscriptionStatus
Roster item subscription status enumeration.
BlockingReason
Reason for blocking an account.
MessageType
Type of message received.
PendingSubscription
Pending subscription states.
PatternMatchResult
Status result of a pattern matching operation.
SearchMethod
Method to traverse the expression structure