Planet Jabber

October 01, 2022

The XMPP Standards Foundation

The XMPP Newsletter September 2022

Welcome to the XMPP Newsletter, great to have you here again! This issue covers the month of September 2022.

Like this newsletter, many projects and their efforts in the XMPP community are a result of people’s voluntary work. If you are happy with the services and software you may be using, especially throughout the current situation, please consider saying thanks or help these projects! Interested in supporting the Newsletter team? Read more at the bottom.

Newsletter translations

This is a community effort, and we would like to thank translators for their contributions. Volunteers are welcome! Translations of the XMPP Newsletter will be released here (with some delay):

XSF Announcements

  • The XSF membership application period for the fourth quarter 2022 is currently open. If you are interested in becoming a XSF member then you can apply for membership. Please submit by November 27, 2022.

  • The XSF Board and Council application period for the next year is currently open. If you are interested in running for the XSF Board or XSF Council then you can apply here. Please submit by November 6, 2022. Remind that XMPP Council members must be elected members of the XSF; however, there is no such restriction for the Board of Directors.

  • Security advisory: libexpat before 2.4.9 is vulnerable to CVE-2022-40674, make sure to update, if you depend on it.

Google Summer of Code 2022

XSF and Google Summer of Code 2022

The Google Summer of Code 2022 finished! The two new contributors Patiga and PawBud were working on open-source software projects in the XMPP environment. Read their all their blog posts, too. Thanks everyone for participation!

XSF fiscal hosting projects

The XSF offers fiscal hosting for XMPP projects. Please apply via Open Collective. For more information, see the announcement blog post. Current projects:



Congrats to the Monal developers for the new NLnet Funding that will cover privacy enhancements for the push servers, an explorative audio and video calls implementation, UI updates for MUC and Contact views, and SASL updates.

Paul Schaub wrote a blog post focused on the technical details of how to check the validity of nested packet sequences using pushdown automata. This technique will be used in a partial rework of PGPainless to validate OpenPGP messages. Earlier this month another post on “Creating a Web-of-Trust Implementation: Accessing Certificate Stores” has been published, too.

PGPainless to validate OpenPGP messages brought voicemail changes and opt-in Jabber ID discoverability to their service, along with an updated Android app and new custom F-Droid repos for both stable and pre-release versions. Furthermore, they wrote about “Privacy and Threat Modelling” in general.

Arnaud wrote about updates on the chatty server and HTTPAuthentificationOverXMPP. published their blogpost XMPP - Teil 1 - Messaging mal anders [DE].

Software news

Clients and applications

Maintenance release of Beagle IM 5.3.1 that fixes sending OMEMO encrypted files and entering password-protected MUC. Besides, Tigase launched a new, simpler website that makes it easier to access open-source projects created by Tigase.


Gajim 1.5.0 and 1.5.1 have been released. These releases come with a significant performance boost. Pinned chats can be ordered via drag and drop, message corrections have been improved, and many bugs have been fixed.

An OMEMO 2 implementation has just been merged to Libervia, coming with Stanza Content Encryption (XEP-0420) support, thanks to the great work of Syndace, author or python-omemo (which has been updated in the process). One of the major benefits is that other Stanza elements can now be encrypted too, not only the body. OX (XEP-0373/XEP-0374) should follow soon, exciting times!

While Monal development is going forward, see the funding news above, and they deployed new Push servers as announced in the July 2022 XMPP Newsletter, users of old Monal versions would need to update, so if you or your contacts didn’t already the developers urge you to do it now.

Missed in the August 2022 XMPP Newsletter was a release of UWPX, the XMPP client for UWP (Windows 10) devices. While version v. has only a fixup it’s unfortunately also the Final Update as the developer is stepping away from the project. Maintainers to follow-up are welcome to reach out!

Kaidan, a user-friendly and modern chat app for every device, will receive a grant by NLnet for adding encrypted audio and video calls. Congratulations!


Jackal v0.62.0 is out bringing XEP-0313 Message Archive Management support and several enhancements.

Metronome IM 4.0 has been released. This version introduces Lua 5.3 support, a revamped shared API for group chats stanza archiving, MIX Core/PAM experimental support, Message Moderation support and support for containerization.

Profanity 0.13.0 has been released.

Libraries & Tools

python-nbxmpp 3.2.2 and 3.2.3 have been released, adding a stringprep implementation and improvements for detecting broken TCP connections.

The first beta of Slidge (XMPP bridges) is out!: Slidge, supporting Signal, Telegram, Discord, Steam, Mattermost, Facebook and Skype. Currently only direct messages are supported, but development is going further. Find the article in English and French.

Work on XMPP ⇔ ActivityPub gateway (supported by a NLnel funding) has been achieved. The gateway supports features such as following/followers, favourite/like (or “noticed” in XMPP terms, reactions (compatible with Pleroma), mentions, sharing/reboost and lastly events (compatible with Mobilizon). It has been tested with Mastodon, Pleroma and Mobilizon. It’s still considered alpha quality, a blog post should follow soon to explain in more details.

Ignite Realtime Community:

Extensions and specifications

Developers and other standards experts from around the world collaborate on these extensions, developing new specifications for emerging practices, and refining existing ways of doing things. Proposed by anybody, the particularly successful ones end up as Final or Active - depending on their type - while others are carefully archived as Deferred. This life cycle is described in XEP-0001, which contains the formal and canonical definitions for the types, states, and processes. Read more about the standards process. Communication around Standards and Extensions happens in the Standards Mailing List (online archive). features a page about XMPP RFCs as well.


The XEP development process starts by writing up an idea and submitting it to the XMPP Editor. Within two weeks, the Council decides whether to accept this proposal as an Experimental XEP.

  • Events
    • This specification describes how to handle calendar events with XMPP


  • No new XEP this month.


If an experimental XEP is not updated for more than twelve months, it will be moved off Experimental to Deferred. If there is another update, it will put the XEP back onto Experimental.

  • No XEPs deferred this month.


  • Version 0.4.0 of XEP-0440 (SASL Channel-Binding Type Capability)
    • Make sasl-channel-binding element a top level stream feature (dg)

Last Call

Last calls are issued once everyone seems satisfied with the current XEP status. After the Council decides whether the XEP seems ready, the XMPP Editor issues a Last Call for comments. The feedback gathered during the Last Call can help improve the XEP before returning it to the Council for advancement to Stable.

  • No Last Call this month.


  • No XEP moved to stable this month.


  • No XEP deprecated this month.

Call for Experience

A Call For Experience - like a Last Call, is an explicit call for comments, but in this case it’s mostly directed at people who’ve implemented, and ideally deployed, the specification. The Council then votes to move it to Final.

  • No Call for Experience this month.

Spread the news!

Please share the news on other networks:

Subscribe to the monthly XMPP newsletter

Also check out our RSS Feed!

Looking for job offers or want to hire a professional consultant for your XMPP project? Visit our XMPP job board.

Help us to build the newsletter

This XMPP Newsletter is produced collaboratively by the XMPP community. Therefore, we would like to thank Adrien Bourmault (neox), alkino, anubis, Benoît Sibaud, emus, goffi, Jeybe, Licaon_Kter, martin, MattJ, MSavoritias (fae,ve), nicfab, Ppjet6, vanitasvitae, wurstsalat, Zash for their support and help in creation, review, translation and deployment. Many thanks to all contributors and their continuous support!

Each month’s newsletter issue is drafted in this simple pad. At the end of each month, the pad’s content is merged into the XSF Github repository. We are always happy to welcome contributors. Do not hesitate to join the discussion in our Comm-Team group chat (MUC) and thereby help us sustain this as a community effort. You have a project and want to spread the news? Please consider sharing your news or events here, and promote it to a large audience.

Tasks we do on a regular basis:

  • gathering news in the XMPP universe
  • short summaries of news and events
  • summary of the monthly communication on extensions (XEPs)
  • review of the newsletter draft
  • preparation of media images
  • translations


This newsletter is published under CC BY-SA license.

October 01, 2022 00:00

September 29, 2022

Ignite Realtime Blog

REST API Openfire plugin 1.10.0 released!

We are happy to announce the immediate availability of version 1.10.0 of the REST API plugin for Openfire!

This release will see the performance on lookups of MUC rooms based on case-insensitive room names, or non-existing rooms. This will be particularly notable in systems that hold many chat rooms.

Another feature that is added is that basic statistics on REST endpoint usage are now exposed. These can be viewed through the Monitoring plugin. It is worth noting that for versions of the Monitoring plugin prior to 2.4.0, Openfire needs to be restarted whenever the REST API plugin is reloaded or upgraded (more details here).

The updated plugin should become available for download in your Openfire admin console in the course of the next few hours. Alternatively, you can download the plugin directly, from the plugin’s archive page.

For other release announcements and news follow us on Twitter

2 posts - 1 participant

Read full topic

by guus at September 29, 2022 19:29

September 28, 2022


Newsletter: Voicemail Changes, Opt-in Jabber ID Discoverability

Hi everyone!

Welcome to the latest edition of your pseudo-monthly JMP update!

In case it’s been a while since you checked out JMP, here’s a refresher: JMP lets you send and receive text and picture messages (and calls) through a real phone number right from your computer, tablet, phone, or anything else that has a Jabber client.  Among other things, JMP has these features: Your phone number on every device; Multiple phone numbers, one app; Free as in Freedom; Share one number with multiple people.

This month sees the release of Cheogram Android 2.10.10-2, based on a new upstream version and with many bugfixes and small improvements, especially around the Command UI. We also now have our own F-Droid repositories for quick update of official builds from us. We have a repository for releases and for those who want to help testing new features as they are developed we also have a repository for pre-releases.

Some JMP customers forward their calls to another voicemail service, or otherwise do not have need for the JMP voicemail.  This month we added an official option to the Configure Calls command that allows disabling voicemail completely for users who need this.

The default voicemail outgoing message has been changed from saying “a user of” to specifying what JMP number has been reached.  Anyone with a name or nickname or custom voicemail greeting set is not affected by this change.

As a small improvement for multi-account billing users, renewal transactions now specify what number is being renewed by the transaction.

Cheogram (and thus JMP) is now allowing all users to opt-in to Jabber ID discoverability.  This is to allow users to discover the true Jabber ID behind a phone number so they can upgrade to end-to-end encryption, video calling, high quality media sharing, etc.  This is opt-in only, and most features that make use of this are not built yet, but we wanted to give people the option to express their consent now.  This is done as part of the registration process.  For existing users, if you do not want to opt in, there is nothing you need to do.  If you wish to opt in, simply run the Register command, choose JMP, and it will ask for your consent (it will show if you use the bot as Current Value true for technical reasons, but do not worry it is set to false unless you explicitly answer yes to that question.)

This month we have also made some progress with the early test phase launch of our data-only SIM and eSIM program.  The program is slowly rolling out to the waiting list over the course of the next month, as we gather data and feedback from early users.  If you are interested, adding your Jabber ID to the waiting list is still the best way.  We have also heard the interest in having these available for people who are not otherwise JMP customers, and hope to have that ready for testing soon as well.

To learn what’s happening with JMP between newsletters, here are some ways you can find out:

Thanks for reading and have a wonderful rest of your week!

by Stephen Paul Weber at September 28, 2022 15:23

Tigase Blog

Tigase XMPP Client Apps

Our XMPP Chat Apps philosophy

Web based, JavaScript, React and so on app are great… for developers.

We do care about users and we understand that the only way to provide users with great experience is through native apps.

Therefore we have put a lot of effort and dedication to develop native client for each platform separately. Each of our apps is tailored for the best experience and native feeling. Plus they are optimized for each platform, so they are lightweight but also powerful and take full advantage of what is offered by the environment they are running on.

All our applications offer the same set of features, so no need to replace them over and over again below. Here is the list:

  • Simple Chat - yes, this is the good, old 1-1 chat.
  • Group Chat - like the old IRC, now it is MUC (Multi User Chat). You can create chat rooms, public or private, open or password protected with moderators and so on…
  • Push notifications - if the app is not running on the device, the user is not connected to the XMPP server but he can still receive notifications about new messages from people.
  • iOS has now call silencing from unknown. We had this before them. All new chats from unknown users go to separate tab “From unknown” and you can turn off push notifications about messages from people who are on on your contact list. Plus, of course Tigase XMPP Server has a built-in anti-spam filtering which helps too.
  • Voice and Video calls are pretty much standard nowadays and Tigase client support it as well.
  • Multi-account support - you can add as many accounts on different servers as you want on your client and communicate through all these accounts at the same time
  • Files Sharing - yes, photos, documents, anything can be send through the XMPP client to your buddies either on the simple 1-1 chat or to entire team in a group chat. Client displays photos nicely, so you can see them directly in the app.
  • OMEMO - E2E encryption is available on all our client apps.

We, at Tigase use all our XMPP apps ourselves.

All Open Source

All our XMPP Chat applications are open source with code available in public repositories on GitHub.

Stork IM - Tigase Android XMPP Client

Our first mobile client we created. Native Android app designed and written from ground up, again and again…

We experimented, made mistakes and learned. So here it is. Android Java, native app. Lightweight, fast and powerful.

Our Android client works on most Android devices. It offers a set of typical features you would expect from a chat application plus a lot more, not typical features.

Siskin IM - Tigase iOS XMPP Client

Our second mobile client. This one for iOS, optimized to run on phones and tablets.

It is a native Swift app optimized for iOS for both phones and tablets.

Simple to use but with many advanced options for more demanding users.

We suggest to start using it in a simple mode and gradually explore other features and options.

Beagle IM - Tigase MacOS XMPP Client

Mobile devices are good when you are on the go. But we are software developers and we work on real computers all the time. Hence we also have and offer a real desktop, native chat client.

Again, it’s a native Swift app designed from ground up and optimized for desktop MacOS.

Feature set matches all other other apps.

If you work on MacOS, we honestly recommend to try it out.

September 28, 2022 00:08

Tigase XMPP Server

Tigase XMPP Server is Java based software

Tigase XMPP Server is a standalone application written in Java. It is not a “web server” system. It runs independently from any other software. In most cases all it needs to run is Java Virtual Machine (JVM). For extended functionality it may require a few external libraries for the most part it is all in-house developed software.

Java based but still very efficient

Java is known and infamous for it’s high resource requirements and slowness. This unfortunate, bad reputation is a result of early impressions from the first years of Java and also from poorly written, bloated Java monster software. Poorly written and poorly maintained software results in tons of redundand code and overall slagishness.

There are, however, many Java programs which are good examples how efficient, fast and resources friendly Java code can be. And Tigase XMPP Server is one of these good examples.

We put a lot of effort to optimize, design it and implement efficient code. Here are some interesting facts:

  • The main binary code to run Tigase XMPP Server is less then 3MB
  • In some cases it can be run with as little as 10MB of RAM, usable, typical XMPP chat system can be deployed on 50MB of RAM
  • It was successfully tested to handle over 30 millions messages per second
  • It runs on production systems with over 10 million users
  • It runs on production systems processing over 5 millions messages per second
  • Typical message processing time is below 0.01 second if database is not involved


We frequently put Tigase XMPP Server through very rigorous testing. Running hundreds of automated tests, performance tests and long-lasting reliability tests. This allows us to discover bugs, inconsistencies, bottlenecks, memory leaks and other potential problems in long-running applications.

Every release is thoroughly tested and verified before publication.

Tigase XMPP Server is known to run for over 3 years without restart on a production system.


XMPP was designed from ground up to be secure. Tigase, however, does not stop there. We took additional steps to make sure Tigase provides up to date security.

Through extensive testing, third-party verification, we make sure it is a well written software, resistant to all common attacks, including SQL injection, DOS attacks, man-in-the-middle attacks and many others.

We closely track changes and developments in the security protocols and make sure Tigase is up to date, uses only safe ciphers and algorithms.

Additional, hardened mode, turns Tigase into very restrictive configuration, which may break connectivity with older apps and servers, but on the other hand, ensures that security it tightest possible for demanding customers.

Very Scalable

Tigase uses resources very efficiently. It can easily handle half a million users on a single server or more. But no matter how efficient the server is and how optimized the software is, there is a limit on how much a single server can handle.

Therefore, from the very beginning we planned on making Tigase scalable. Out of the box Tigase offers near-linear scalability or exact linear for some use cases.

It can be deployed on large number of servers over distributed data centers and cloud providers to provide a single logical system for practically unlimited number of online users sending millions of messages per second.

Cloud independent

Tigase XMPP Server is Java application and can be deployed on anything that can run Java programs. It does have some special integration features for Amazon AWS cloud system but it can run on any Cloud. Our customers deploy Tigase on Google Cloud, Microsoft Azure cloud and many others and also on in-house dedicated data centers.

Tigase has a built-in load balancer to better distribute connected users and devices but it can also play nicely with external load balancers which are used on different environments.


Tigase XMPP Server can be used as it is.

Out of the box it is capable to provide sufficient functions for typical XMPP systems and in many cases for not so standard XMPP services.

There are, however, deployments with specific requirements or third-party systems with which Tigase has to integrate. For such cases, Tigase XMPP Server offers exceptional flexibility. Well designed and rich API allows adding custom elements like blocks.

There is no single line of code in Tigase which is fixed. Anything and everything can be replaced with custom made code and plugged-in through configuration file.

Administrator friendly

From our experience we know that starting a complex system is a big challenge. However, even greater challenge is maintaining such a system long-term. Therefore, we have put a lot of effort to make sys ops life easier.

There is a huge number of tools built-into the Tigase XMPP Server which make maintaining Tigase much simpler than expected:

  • Command line tool to execute all admin tasks
  • Web UI for admin to see critical system parameters and performance metrics
  • Thousands of runtime performance metrics allow to diagnose system in real-time
  • Built-in self-monitoring system which can send notifications via email or XMPP if it detects problems
  • Detailed diagnostic log can be switched on/off
  • Detailed diagnostic log for a single user can be switched on/off
  • Audit Log
  • Self-fault recovery
  • Automatic cluster reconfiguration

Easy to track performance

Proper monitoring is one of key areas we focus during development, testing and maintaining services. Tigase XMPP Server offers thousands of run-time performance metrics, which allow to track the system in real-time.

Every significant processing unit generates performance metrics, therefore if there is any slow down or a bottleneck it is very easy to diagnose the system, locate the problem and fix it.

Easy to integrate

There are many ways to integrate third-party systems with Tigase XMPP Server.

It has very well thought and rich API which allows to add new components and plugins. These plugins can interact with other systems to exchange information.

However, Tigase employs a common pattern for so called “Connection Managers” which are responsible for network communication. Each connection manager talks a different protocol and Tigase can easily learn new protocols to connect to virtually any external service to exchange information in real-time.

Tigase also offer access through REST API which can be easily extended using various scripting languages. This is a powerful feature which allows to add new REST API calls using a programming language of your choice.

Tigase XMPP Server can be also configured to retrieve users’ data from different databases storing data in different formats. This allows for an easy integration with other systems without writing a single line of code.

September 28, 2022 00:08

Tigase XMPP Libraries

Our software philosophy

Actually nothing new and nothing surprising here. We want to have as much of a reusable code as possible. And this reusable code should have a simple but powerful API to be useful for quickly creating software.

That’s it.

And this is how we design and develop our XMPP libraries. Check them out.

Documentation to all our projects is available online and sample codes? Take a look at our XMPP Chat apps which are open source too.

September 28, 2022 00:08

Tigase Instant Communication, Presence and Messaging

What is “Instant Communication”

First things first. What is this all about?

We say this is “Instant communication” or “Near real-time communication” and indeed, this is about communicating, talking, sending messages, sending other information, documents. Instant or real-time means, whatever you send, is sent right away, it is also delivered right away.

Would the receiving person get it right away too? Well, it depends, if the person is online, it gets it right away and can respond right away.

Messaging really means chatting, talking. It’s not just sending and receiving messages. You send a message, friend receives it in real-time and can respond right away. You see the full chat history, context, you just talk. And you can chat with many people at the same time, in what we call group chat rooms. It’s like sitting at the table with friends and talking to them.

What special about this system is, that You know if your friends are online. If you send a message to online friend you can expect his response right away, if he is offline, you know about it and you know you may have to wait for a response. No guessing. This is the “Presence” part in the title. Presence is just a status of the other person: online, offline, busy, away, and so on… So you not only can send a message to your friend instantly but also can know his current status, also in real-time. As soon as somebody changes his status, you know it right away.

Presence is also much more than just online status. Presence can optionally carry on additional information, like location, mood, what your friends are listening to and just anything your friend chooses to share with you.

And… “last but not least”, the system is not just for people talking. It’s for devices as well. Anything that can send some information, share some data, update it’s status can effectively use our software. IoT is an ideal example where our software excels and shows it’s full power.

How is it different from e-mail?

Simple enough. It all looks similar to email, send and receive messages. What’s more, even a user address looks exactly like email. So what is the difference?

There are a few significant differences:

  1. E-mail is not real-time and is not instant. It may be quite fast but it may also be quite slow (a couple of minutes) until the email is actually delivered and this is still considered a norm for email messages.

    XMPP is actually near real-time and instant. Typical delivery time is way below 1 second.

  2. E-mail is not really for chatting or talking. It’s more like sending letters, longer texts. It’s not really suitable for sending short messages or notifications.

    XMPP is just for that. Chatting, talking, sending short messages or notifications. However our software has expanded on the basic features and allows rich text formatting using Markdown language. You can send long texts and even letters nicely formatter which are pleasant to read.

  3. E-mail has no presence information. You send an email message but you do not know whether your friend is online, when he gets the message, when he can read the message and finally respond. You just send an email and wait.

    XMPP does have presence information. Plus all kinds of confirmations built-in. You know if your friend is online, when he received the message, read it and you know when to expect a response. You know whether your friend is available to talk right now or busy doing something.

  4. E-mail was designed and created very long time ago. When the high security and privacy was not such a big concern, there was no spam, and other attacks. Over time security of email improved but there are many different techniques and standards not always adopted by every email provider. Spam has been a huge problem for a long time and so far nobody knows how to solve it.

    XMPP came to be long time after e-mail. When all the email weaknesses and problems were well known. So it was designed from ground up to solve the problems. Security is embedded in the XMPP core, privacy was the main concern and preventing Spam and DOS attacks was taken into consideration from the very beginning.

How is it different from SMS / Text Messages?

SMS / Text messages are instant, aren’t they? They are sent and delivered in real-time, aren’t they?

At first, it all sounds like SMS / Texting. People chat over SMS all the time. Is XMPP any different.

There are a few significant differences:

  1. Presence - is completely missing from SMS/Texting. You have no idea whether the person is at their device to read the message and text you back. You are sure, that he gets the message, usually, right away, unless their device is turned off. But you have no way of knowing if the device is on or off, whether your friend is close by to the device, and not busy to respond.
  2. User address/ID - for SMS / Texting, this is just a phone number. Sure, nowadays it is kind of personal thing but if it changes, then friends may have problem finding out your new number, may have problem contacting you at all. So you have to take a good care of letting them know about the phone number change. But even if you have still your number and poeple can text you, the device may be far on the table when you rest on the coach with your tablet. To read a text from a friend or send somebody SMS you would have to interrupt your rest, find your phone and type the message on the screen. Don’t mention about all your chat history. When your mobile is gone, all the SMSes / Texts are gone too.

    With XMPP, this problem does not exist. You can have multiple applications connected to your one user address and can chat with friends using whatever device you have handy with you. And all your friends will always recognize you as you. And you can choose to store your chat history on the server and you can see it on any devices and app you connect with.

  3. Chat feedback. With SMS / Text you send a message and… wait. In XMPP, you send a message, you see when it was delivered, you also see when the friend read it and finally you can even see when the friend starts typing response.

How is it different from Twitter, FB?

Twitter and Facebook are social networking services. Although you can send a message to other people, these services are not really designed for effective, real-time communication. They are more like publications, where you can post a message, a longer article, photo or just anything for people to see, when they come over to your profile.

In theory, the XMPP in it’s core can do all that can be done on Twitter and Facebook and also so much more. It’s just a matter of implementing apps that can make use of all the XMPP capabilities.

The Tigase XMPP Server could serve as a social networking platform out of the box and there already are systems like this. Our focus, however, is on real-time communication, hence our apps are designed as effective messaging clients.

How is it different from Skype, ICQ, AIM, FB Messenger, iMessage and others big names?

Ok, so, there are chat / messaging systems available already. They are instant and near real-time. Big brands are behind them they are not going anywhere any time soon. They also offer voice and video calls and all the features and maybe even more.

How XMPP is different and how Tigase is different and better then?

First of all XMPP is a public and open standard. So, you know what is under the hood, how it works, you can evaluate if it is secure. You can easily create own tools, apps, servers to connect to the world wide XMPP network. Well, the XMPP by desgin is extensible, so you can easily customize and extend the basic XMPP protocol with more features and capabilities.

None of this is true for the big name systems.

You do not really know how your messages are sent and delivered by the big names. How your personal data is handled. Even if you assume, they are big with big pockets, so they can implement secure systems and can take care of your data. There are other important questions: It safe? Who has access to it? Would they sell your profile to third-party?

XMPP and Tigase for that matter allows you to deploy your own instant communication system, independent from any other, you keep all your data, you control everything, you decide what is allowed, who can communicate with whom. And still while having independent system for your needs, you can communicate with other users who are on XMPP.

And if you want some extra features, customization, there is no way to have it on the big name systems. You just have to rely on what is there and adjust yourself to what is available.

How is it different from Slack?

And again, it all sounds like Slack. So similar in every aspect. Is there any difference?

Indeed there is. In principle XMPP has all the same features as Slack has. Probably even some more. The main differene is that with XMPP you can choose software vendor (Tigase is one of them but there are many others), deploy your own system, independent which is under your full control, you keep your data and you decide what happens with them.

September 28, 2022 00:08

September 20, 2022


Privacy and Threat Modelling

One often hears people ask if a product or service is “good for privacy” or if some practice they intend to incorporate is “good enough” for their privacy needs.  The problem with most such questions is that they often lack the necessary context, called a threat model, in order to even begin to understand how to answer them.  Understanding your own threat model (and making any implicit model you carry more explicit to yourself) is one of the most important steps you can take to improve your privacy.

What is a Threat Model?

A threat model is a list of possible vulnerabilities, often with attached priorities.  In the context of personal privacy, this includes anyone who you might not want to learn private information about you, what private information you most want that party to remain ignorant of, and why.  For example, someone may not want their ISP to learn that they are communicating on LGBTQ+ forums, because their ISP is their school and their school might tell their parents, whom they are not yet ready to tell.  In this example they might say “I don’t want the school to learn” but because of the reasons it may actually be more important to say “I don’t want my parents to learn.”  So the ISP, the school, and the parents all represent potential vulnerabilities, with the parents as the most important.

Why is a Threat Model Important?

You cannot protect your privacy unless you know what your are protecting and what you are defending against.  Otherwise you may take extra steps to secure something not worth protecting, omit something you were unaware needed protected, or even protect something at the detriment of something you would have cared more about.  Privacy is not a slider from zero to infinity, you cannot be simply “more” or “less” private in some general abstract way.

For example, someone may be a part of a group of insurgents in a small country.  They wish the contents of their communication to be kept a secret from the current government if any one of them is found out, so they choose to use an end-to-end encrypted messaging app.  They have prevented their mobile carrier and government from logging their messages!  They also secure their devices with biometrics so they cannot be stolen.  However, due to the unpopularity of this app in their country, when asked the carrier can immediately identify the current location of anyone using it.  When any of these people are brought in for questioning, the investigator forces the biometric (face or fingerprint) onto the device from the person in custody, unlocks it, gets access to all the decrypted messages, and let’s just say the insurgency is over.

So did the insurgents make “un-private” choices?  No!  For other people with different vulnerabilities, their choices may have been ideal.  But when their identity and current location is more at risk than the content of their messages, sending messages less-encrypted over a more-popular app or protocol (which could have all contents logged for all users, but very likely does not), and deleting them regularly from the local device in case they are caught, would have been more effective.

Privacy LARPing

“Privacy LARPing” is what happens when someone wants to be “more private” because it is cool and not because they have any well-reasoned need for privacy.  Believe it or not, this kind of use case also has a threat model.  The model may be more built on what kinds of vulnerabilities are currently trendy to defend against, but it exists nonetheless.  Putting thought and explicit description into your threat model can be a great way to seem even more “with it” so it’s highly recommended.  You may even identify real threats of concern (there certainly are some for everyone) and move beyond the LARP and into addressing your real needs.

How to Build a Threat Model

This is really an introspection activity.  Ask yourself what kind of entities are most concerning to you.  Estranged friends or lovers?  The other people at the airport or coffee shop?  Local police?  Local SUV owners?  Federal agencies?  Data brokers?  The list of people who may want to know more about you than you want them to is endless, so revisit your model from time to time.  Try to add to it and refine it.  This kind of work is never “done” because the scope is so vast.  Do talk to others and educate yourself about what the set of possible threats is, but do not take each new threat you learn about with the same weight.  Try to understand whether mitigations or new techniques are able to acheieve what you need, rather than blindly applying every “defense” without regard for context.

by Stephen Paul Weber at September 20, 2022 02:14

September 19, 2022


Gajim 1.5.0 / 1.5.1

Gajim 1.5.0 and 1.5.1 come with a significant performance boost. Pinned chats can be ordered via drag and drop, message corrections have been improved, and many bugs have been fixed.

What’s New

For many years, Gajim’s internal handling of how a chat is loaded and displayed hasn’t changed. Each chat would create a new Control, which would hold the chat banner (name, chat state, etc.), the conversation view (messages), and a message input, including actions and menus. This approach does not scale well, since Gajim’s resource usage would increase with every new chat. With Gajim 1.4, we introduced a new conversation view, which increases the overall number of elements being displayed at the same time. Multiply this by the number of open chats, and you’ll get a lot more elements, which have to be rendered all at once. Due to some GTK theming issues (looking at you, backdrop animation), every focus/defocus of Gajim would lead to a spike in CPU usage.

To overcome these limitations, we changed Gajim’s fundamentals. The whole chat window with all its elements is now created only once, and then shared between all chats. Gajim just switches each element’s state when switching chats. Due to a drastically reduced amount of elements being loaded, this change alone reduces Gajim’s RAM usage by 20 %. With less elements being rendered at once, the delay ‘from click to action’ is also significantly reduced. In other words: Using Gajim feels more snappy.

Gajim 1.5

Gajim 1.5

More Changes


  • Drag and drop for ordering pinned chats
  • Use Ctrl+Number to switch between workspaces
  • The chat list can now be toggled using a button or Ctrl+R


  • Chat command system has been reworked
  • Message corrections are now available from the message menu
  • Windows: Overall text size has been increased
  • Ctrl+F replaces Ctrl+H for opening the search bar
  • Advanced Configuration Editor (ACE): non-default settings are highlighted
  • Syntax highlighting for the XML console’s input
  • IPython support has been removed


Over 40 issues have been fixed in this release.

Due to a bug found shortly after releasing Gajim 1.5.0, it was necessary to release Gajim 1.5.1.

Have a look at the changelog for the complete list.


As always, don’t hesitate to contact us at or open an issue on our Gitlab.

September 19, 2022 00:00

September 16, 2022

Ignite Realtime Blog

New Openfire plugin: Push Server!

The Ignite Realtime Community is pleased to announce the 1.0.0 release of the Push Server plugin for Openfire. This plugin is developed by the company Busoft Teknoloji A.Ş. It is inspired by Conversations Push Proxy and developed for Openfire.

Your instance of Openfire should automatically display the availability of the new plugin in the next few hours. Alternatively, you can download the the plugin directly from the Push Server plugin archive page.

Stop by our support groupchat to get in touch, or leave a message on our community site.

For other release announcements and news follow us on Twitter

What is this plugin for

Due to the restrictions in push services (FCM or APNS), only the developer can create push notifications for their apps. For this reason a user’s server wouldn’t be able to wake up a user’s device directly but has to proxy that wake up signal through the infrastructure of the app developer.

Push Server Plugin is an XEP-0357: Push Notifications app server that relays push messages between the user’s server and FCM (Firebase Cloud Messaging) or APNS (Apple Push Notification Service).

Here is a quick description of how this relationship is set up.

XMPP Client sends to the app server

- Device Token
- Device Id

App Server generates

- Node Id
- Secret

App Server stores

- Device Token
- Device Id
- Node
- Secret

App Server returns to XMPP Client

- Node Id

XMPP Client sends to the user's server

- Node ID
- The jid of the app server (

The user’s server sends to the app server

(Achived by Openfire Push Notification plugin)

When a push is required the user’s server will send the node id to the app server. The user’s server can also add additonal information like number of messages pending, the sender jid of the last message and even the body of the last message.

An example of that communication can be found in XEP-0357 Section 7.

7 posts - 3 participants

Read full topic

by hamzaozturk at September 16, 2022 13:15

September 14, 2022

Paul Schaub

Using Pushdown Automata to verify Packet Sequences

As a software developer, most of my work day is spent working practically by coding and hacking away. Recently though I stumbled across an interesting problem which required another, more theoretical approach;

An OpenPGP message contains of a sequence of packets. There are signatures, encrypted data packets and their accompanying encrypted session keys, compressed data and literal data, the latter being the packet that in the end contains the plaintext body of the message.

Those packets can be sequential, e.g. a one-pass-signature followed by a literal data packet and then a signature, or nested, where for example an encrypted data packet contains a compressed data packet, in turn containing a literal data packet. A typical OpenPGP message can be visualized as follows:

A typical encrypted, signed OpenPGP message

This particular message consists of a sequence of Public-Key Encrypted Session Keys (PKESKs), followed by a Symmetrically Encrypted Integrity-Protected Data packet (SEIPD), and Modification Detection Code packet (MDC). Decrypting the SEIPD using the session key obtained from any of the PKESKs by providing an OpenPGP secret key yields a new data stream consisting of a OnePassSignature (OPS) followed by a Compressed Data packet and a Signature. Decompressing the Compressed Data packet yields a Literal Data packet which in turn contains the plaintext of the message.

I am pretty confident that PGPainless can currently handle all possible combinations of packets just fine. Basically it simply reads the next packet, processes it in however way the packet needs to be processed and then reads the next packet. That makes it very powerful, but there is a catch! Not possible combinations are valid!

The RFC contains a section describing the syntax of OpenPGP messages using a set of expressions which form a context-free grammar:

11.3.  OpenPGP Messages

An OpenPGP message is a packet or sequence of packets that corresponds to the following grammatical rules (comma  represents sequential composition, and vertical bar separates alternatives):

   OpenPGP Message :- Encrypted Message | Signed Message |
                      Compressed Message | Literal Message.

   Compressed Message :- Compressed Data Packet.

   Literal Message :- Literal Data Packet.

   ESK :- Public-Key Encrypted Session Key Packet |
          Symmetric-Key Encrypted Session Key Packet.

   ESK Sequence :- ESK | ESK Sequence, ESK.

   Encrypted Data :- Symmetrically Encrypted Data Packet |
         Symmetrically Encrypted Integrity Protected Data Packet

   Encrypted Message :- Encrypted Data | ESK Sequence, Encrypted Data.

   One-Pass Signed Message :- One-Pass Signature Packet,
               OpenPGP Message, Corresponding Signature Packet.

   Signed Message :- Signature Packet, OpenPGP Message |
               One-Pass Signed Message.

In addition, decrypting a Symmetrically Encrypted Data packet or a Symmetrically Encrypted Integrity Protected Data packet as well as decompressing a Compressed Data packet must yield a valid OpenPGP Message.

Using this grammar, we can construct OpenPGP messages by starting with the term “OpenPGP Message” and iteratively replacing parts of it according to the rules until only final “Packet” terms are left.

Let’s create the message from the diagram above to illustrate the process:

OpenPGP Message
-> Encrypted Message
-> ESK Sequence, Encrypted Data
-> ESK, ESK Sequence, Encrypted Data
-> ESK, ESK, Encrypted Data
-> SKESK, ESK, Encrypted Data
-> SKESK, SKESK, Encrypted Data
-> SKESK, SKESK, SEIPD(Signed Message)
-> SKESK, SKESK, SEIPD(One-Pass Signed Message)
-> SKESK, SKESK, SEIPD(OPS, OpenPGP Message, Sig)
-> SKESK, SKESK, SEIPD(OPS, Compressed Message, Sig)
-> SKESK, SKESK, SEIPD(OPS, Compressed Packet(OpenPGP Message), Sig)
-> SKESK, SKESK, SEIPD(OPS, Compressed Packet(Literal Message), Sig)
-> SKESK, SKESK, SEIPD(OPS, Compressed Packet(Literal Packet("Hello, World!")), Sig)

Here, cursive text marks the term that gets replaced in the next step. Bold text marks final OpenPGP packets which are not being replaced any further. Text inside of braces symbolizes nested data, which is the content of the packet before the braces. Some packet terms were abbreviated to make the text fit into individual lines.

Now, applying the rules in the “forwards direction” as we just did is rather simple and if no non-final terms are left, we end up with a valid OpenPGP message. There are infinitely many solutions for “valid” OpenPGP messages. A brief selection:

Literal Packet("Hello, World")
OPS, Literal Packet("Hey!"), Sig
OPS, OPS, Literal Packet("Hoh!"), Sig, Sig
SEIPD(Literal Packet("Wow"))
Sig, Compressed Packet(Literal Packet("Yay"))

On the other hand, some examples for invalid OpenPGP packet streams:

Literal Packet(_), Literal Packet(_)
OPS, Compressed Packet(<empty>), Sig
Literal Packet(_), Sig
OPS, Literal Packet(_)
SKESK, SEIPD(Literal Packet(_)), Literal Packet(_)

Give it a try, I can guarantee you, you cannot create these messages using the OpenPGP grammar when starting with the term OpenPGP Message.

So now the problem becomes: How can we check, whether a given OpenPGP packet stream forms a valid OpenPGP message according to the grammar? Surely just trying to reverse engineer the message structure manually by brute force would be a daunting task… Luckily, theoretical computer science has a solution for us: Pushdown Automata!

Note: The following description of a PDA is kept brief and simplistic. I may well have made imprecise simplifications on the formal definition. If you want to learn more, but care about correctness, or if you are reading this post in preparation for an exam, you really should check out the Wikipedia page linked above instead.
Me, perhaps not totally accurate on the internet

A Pushdown Automaton (PDA) consists of a set of states with transition rules between those states, as well as a stack. It further has an initial state, as well as a set of accepting states. Each time the automaton reads an input symbol from a word (in our case a packet from a packet stream), it pops the top most item from the stack and then checks, if there is a transition from its current state using the given input and stack item to another state. If there is, it transitions into that state, possibly pushing a new item onto the stack, according to the transition rule. If all input symbols have been read, the word (packet stream) is valid if and only if current state is an accepting state, the stack of the automaton is empty and there are no more input symbols left. If the current state is not accepting or if the stack of the automaton is not empty, the word is invalid.

Formally defined, a transition rule is a tuple (state, input-symbol, stack-symbol, state, stack-symbol), where the first state is the origin, the first stack-symbol is what needs to be popped from the stack, the second state is the destination and the second stack-symbol what we push back onto the stack.

There is a special symbol ‘ε’ which means “nothing”. If the input symbol is ε, it means we can apply the rule without reading any input. If a stack symbol is nothing it means we can apply the rule without popping or pushing the stack.

I translated the OpenPGP grammar into a PDA. There is an initial state “start”, a single accepting state “Valid” and a set of transition rules which I annotated with arrows in the following diagram. Let’s take a closer look.

Let’s say we want to validate an OpenPGP message of the format OPS, Literal Packet(_), Sig.

We start with the “start” state to the left. As you can see, the only rule we can apply now is labelled ε,ε/m#, which means we do not read any input and do not pop the stack, but we push ‘#’ and ‘m’ onto the stack. After we applied the rule, we are in the state labelled “OpenPGP Message” and the top of our stack contains the symbol ‘m’.

To advance from here, we can peek at our stack and at the input to check our options. Since our message begins with a One-Pass-Signature (OPS), the only rule we can now apply is OPS,m/o, which requires that the top stack symbol is ‘m’. We read “OPS”, pop ‘m’ from the stack, push ‘o’ onto it and transition into the state “One-Pass-Signed Message”. From here there is only one rule ε,ε/m, which means we simply push ‘m’ onto the stack without popping an item and without reading input. That leaves us back in the state “OpenPGP Message”. Our stack now contains (top to bottom) ‘mo#’.

Now we read the next input symbol “Literal Packet” and apply the rule Literal Packet,m/ε, which means we pop ‘m’ from the stack and transition into state “Literal Message”. The stack now contains ‘o#’.

Next, we read “Sig” from the input, pop ‘o’ from the stack without pushing back an item, transitioning to state “Corresponding Signature”.

Last but not least, we apply rule ε,#/ε, do not read from the input, but pop the top symbol ‘#’ from the stack, transitioning to state “Valid”.

In the end, our stack is empty, we read all of the input data and ended up in an accepting state; The packet sequence “OPS, Literal Packet, Sig” forms a valid OpenPGP message.

Would we start over, but with an invalid input like “Literal Packet, Sig”, the play would go like this:

First, we transition from “start” to “OpenPGP Message” by pushing ‘#’ and ‘m’ to the stack. Then we apply rule Literal Packet,m/ε, read “Literal Packet” from the input, pop ‘m’ from the stack without pushing anything back onto it. This brings us into state “Literal Message” with ‘#’ being our new stack symbol. From here, we only have two rules that we could apply: Sig,o/ε would require us to read “Sig” from the input and have ‘o’ on the top of our stack. Both of these requirements we cannot fulfill. The other option ε,#/ε requires us to pop ‘#’ from the stack without reading input. It even brings us into a state called “Valid”! Okay, let’s do that then!

So far we have read “Literal Packet” from the packet stream. Would the data stream end here, we would have a valid OpenPGP message. Unfortunately, there is still some input left. However, there are no valid rules which allow us to transition any further with input “Sig”. Therefore, the input “Literal Packet, Sig” is not a valid OpenPGP message.

You can try any of the invalid messages listed above and you will see that you will always end up in a situation where you either have not fully read all the input symbols, your stack is not empty, or you end up in a non-accepting state.

You might notice some transitions are drawn using dashed lines. Those illustrate transitions for validating the content of nested packets. For example the Compressed Packet MUST contain another valid OpenPGP message. Depending on how you implement the PDA in software, you can either replace the input stream and use the nested transitions which require you to jump back from a nested “Valid” to the state where the nested transition originated from, or use child PDAs as described below.

The packet sequence Compressed Packet(Literal Packet(_)) for example would be resolved like follows:

From “start” we transition to “OpenPGP Message” by pushing ‘#’ and ‘m’ on the stack. The we read “Compressed Packet from input, pop ‘m’ from the stack and transition to state “Compressed Message”. Since the “Literal Packet” is part of the Compressed Packet”s contents, we now create a new child PDA with input stream “Literal Packet”. After initializing this PDA by pushing ‘#’ and ‘m’ to the stack, we then transition from “OpenPGP Message” to “Literal Message” by reading “Literal Packet” and popping ‘m’, after which we transition to “Valid” by popping ‘#’. Now this PDA is ended up in a valid state, so our parent PDA can transition from “Compressed Message” by reading nothing from the input (remember, the “Compressed Packet” was the only packet in this PDAs stream), popping ‘#’, leaving us with an empty stack and empty input in the valid state.

In PGPainless’ code I am planning to implement OpenPGP message validation by using InputStreams with individual PDAs. If a packet contains nested data (such as the Compressed or Encrypted Packet), a new InputStream will be opened on the decompressed/decrypted data. This new InputStream will in turn have a its own PDA to ensure that the content of the packet forms a valid OpenPGP message on its own. The parent stream on the other hand must check, whether the PDA of it’s child stream ended up in a valid state before accepting its own packet stream.

Initial tests already show promising results, so stay tuned for another blog post where I might go into more details on the implementation 🙂

I really enjoyed this journey into the realm of theoretical computer science. It was a welcome change to my normal day-to-day programming.

Happy Hacking!

by vanitasvitae at September 14, 2022 21:46

September 12, 2022

Maxime Buquet


I finally took time to setup a forge and some old drafts turned up. I am publishing one of them today as is even though it’s 4 years old (2018-08-07T13:27:43+01:00). I’m not as grumpy as I was at the time but I still think this applies.

Today I am grumpy at people’s expectation of a free software project, about versioning and releases. I am mostly concerned about applications rather than libraries in this article but I am sure some of this would apply to libraries as well.

Today we were discussing about versioning and releases in the poezio chatroom.

Poezio is a console application, a small project maintained by a handful of contributors to which I am grateful. I also have a few contributions myself. The application is far from perfect but what software is anyway.

The last release – as of writing – for the project is 0.11, published on Jan 31, 2017. A bit over 1.5 years ago. Yes, the project is still being actively maintained, but no release is being made for the moment.

No, not every project releases with the same regularity. No, not every project has the same understanding of what a release is. Most projects don’t have the same constraints.

For some projects releases are sacred and I am happy for them. Maintained for X months or even years to which will only be applied security fixes or critical bug fixes (crashes and the like).

For others, releases are only checkpoints. A way of saying that features are being added, bugs are being fixed, and have people talk about it.

There is no global definition of what a release is supposed to be. It is up to project maintainers to decide what they want to see in it. They could very well make a release every other commit and be happy with it if they wanted to be silly. They would still be semver compliant – one of the various versioning scheme defined out there.

Nothing also mandates they have to backport bug fixes to the current or previous releases, and some projects actually cannot afford such a luxury. All of this takes time and that is a really expensive resource in a project.

Update from the present:

I think the issue I tried to convey in this article isn’t that we don’t have time, or that there’s no definition of a release, it’s that I’m tired of being imposed a vision of the world I don’t agree with. What’s more, people having these expectations often don’t even take part in the process of making the project or the in community around it, at any level.

by pep. ( at September 12, 2022 08:00

September 11, 2022

Arnaud Joset

Updates: chatty server and HTTPAuthentificationOverXMPP

It's been a long time since I updated this blog. It will be a short update post about two projects.


The first is chatty_server, a small XMPP bot I use to interact with my server. It allows me to get information about the CPU load, traffic, weather etc. It also has a small feature to get reminder messages. There was a bug that allowed anyone to spam reminders. Anybody can add the bot to their rooster and could create random reminders that I would get. I got none, so the bot must remain quite unheard-of.


The second project is HTTPAuthentificationOverXMPP, a component that I use to allow 2 Factor authentication with XMPP. The original project had not been updated for a long time and I wanted to try to modify it to rely on another XMPP go library. I have never coded in Go and it seemed like a nice introduction. I relied on go-xmpp where I added the support for XEP 0070. It was really interesting. The new component is running for several months and I am quite happy with it even if I don't have any serious project relying on it.

The website is still up if you want to test it.
I hope being able to provide more update about my projects in the future :-).


by Arnaud at September 11, 2022 13:00

September 10, 2022

Monal IM

Monal IM – project moved

We recently started to migrate the App from Anu Pokharel‘s Apple account to Thilo Molitor‘s Apple account.

As part of this transition we also deployed some new push servers to not let an old retired developer pay for the infrastructure needed for Monal.

Coming along with this transition from the old developer team to the new one is our new clean website at From now on, this blog will not be used for Monal anymore.

Many thanks to all users, contributors and followers so far.

Special thanks goes to Anu. Without him and his passion, Monal would not have been possible. He developed and maintained Monal for more than 10 years, always ensuring compatibility with the latest iOS releases.

When I (Thilo) gradually took over development, I was able to build upon an app with a decent codebase rather than writing my own app from scratch. That made it possible to improve Monal further while already being used by thousands of people. I can not stress enough how thankful I was and still am for all the work Anu put into the development of Monal.
Thank you, Anu, for your wonderful work towards a modern XMPP client for iOS and macOS!

Thilo, Friedrich, Anu

by Thilo at September 10, 2022 15:24

September 09, 2022


Stateless File Sharing: Async, Metadata with Thumbnails and some UI


Asynchronous programming is a neat tool, until you work with a foreign project in a foreign language using it. As a messenger, Dino uses lots of asynchronous code, not always though. Usually my progress wasn’t interfered by such instances, but sometimes I had to work around it.

Async in Vala

No surprises here. Functions are annotated with async, and yield expressions that are asynchronous themselves. And you can’t easily call async methods directly in non-async functions.

Creating problems

I had a async function I wanted to call in a synchronous context. For quick prototyping, I wanted to call that function and get the result directly by blocking. However, the furthest I got there was a variable in a function that is only initialized if you access it late enough (wouldn’t recommend). At that point I restructured the code so that the async call would actually be in an async context with a simple yield.

Here a proper introduction to Vala async.


With the introduction of the metadata element, more metadata can be extracted from files and attached to file transfers. You wouldn’t have guessed, but there are actually a rather big variety of file types. So not only do different files use different metadata fields, but they can also use the fields in different ways.

To accommodate that relation, the FileManager module now keeps a list of FileMetadataProviders, which will be extended over time. When a file is sent, each provider is asked if it is compatible with the file. If yes, it is called. The first provider is a generic one which is called for every file and fills in name, last-edit-date, size, mime-type and hashes.

Thumbnail creation

A special new field is a list of thumbnails. They are intended for small previews of whichever file it is attached to, be it a image, video or pdf. So far, I have implemented thumbnails for images, which introduced two design decisions.

Size: Which dimensions should the preview have? When it is displayed, it should be stretched to the format of the original image, so the aspect ratio should sort of match. My mentor, larma, suggested that we create very small thumbnails for now, about 8 or 9 pixels. Which dimensions would that allow? 1x8, 2x4, 3x3, 4x2, 8x1. Well, that sounds pretty diverse, no? Those are the dimensions that we use for now, and I select the dimension with the closest aspect ratio.

Scaling: Now that we have the size, how do we scale the image? Luckily, Gtk (which Vala is closely integrated with), has scaling methods for images. So far, I used bilinear scaling, which is usually the suggested method according to the docs. However, scaling to such a small size results in a lot of gray. While you could probably come up with a fancy custom-made algorithm, I’ll stick with the Gtk built-in methods. Maybe nearest-neighbor could be a better choice, because it would show a ’true’ color from the original image.


I tried to hold off on UI work until the last weeks of the projects. While this could’ve easily been due to procrastination (I don’t enjoy UI coding a lot), I actually have a good excuse here. The Dino codebase is being migrated to Gtk4 from Gtk3 this year. Due to this, a lot of UI code is being rewritten, and it would’ve been wasted work to implement new UI elements in the old codebase. The new UI element I introduced is the FilePreviewWidget, which holds a thumbnail of files which are so large that they aren’t immediately downloaded (currently >5 MB). Luckily, the user interaction and graphical components are really close to the FileImageWidget and FileDefaultWidget, so the implementation wasn’t that difficult.


We are nearly finished. The one thing left is source attaching, which the next (and last) progress post will cover. Like always, you can track my progress on the stateless-file-sharing branch. I also created a pre-gtk4-rebase branch stateless-file-sharing-pre-gtk4.

September 09, 2022 00:00

September 07, 2022

The XMPP Standards Foundation

The XMPP Newsletter August 2022

Welcome to the XMPP Newsletter, great to have you here again! This issue covers the month of August 2022.

Like this newsletter, many projects and their efforts in the XMPP community are a result of people’s voluntary work. If you are happy with the services and software you may be using, especially throughout the current situation, please consider saying thanks or help these projects! Interested in supporting the Newsletter team? Read more at the bottom.

Newsletter translations

This is a community effort, and we would like to thank translators for their contributions. Volunteers are welcome! Translations of the XMPP Newsletter will be released here (with some delay):

XSF Announcements

  • The XSF membership application period for the fourth quarter 2022 is currently open. If you are interested in becoming a XSF member then you can apply for membership. Please submit by November 27, 2022.

Google Summer of Code 2022

XSF and Google Summer of Code 2022

The Google Summer of Code 2022 has lifted off and coding started a while ago! The two new contributors Patiga and PawBud who will work on open-source software projects in the XMPP environment. Read their first blog posts, too.

XSF fiscal hosting projects

The XSF offers fiscal hosting for XMPP projects. Please apply via Open Collective. For more information, see the announcement blog post. Current projects:



Prosody’s team announces a rework of their permission system in context of modernizing XMPP authentication and authorization. published two articles:

JMP newsletter announces a new major release of the Cheogram Android client, with support for ad-hoc command UI and more, as well as a new multi-account billing feature. They also have an article showcasing the command UI in pictures.

Anoxinon Media published “XMPP - Teil 1 - Messaging mal anders” [DE]. It is about XMPP - an alternative that stands out from the mass.

Kaidan, the XMPP client for every device, released a post about its end-to-end encryption trust management QR code scan

The Mellium Dev Communiqué for August 2022 outlines development for the past month including support for HTTP Upload, RFC 9266, various internal testing changes, and a call for feedback!

Easy Onboarding with Android Chat App via XMPP Providers! Passwords are generated automatically and XMPP providers are suggested. Those suggestions are based on the curated list of XMPP Providers project.

Software news

Clients and applications

Conversations 2.10.9 and 2.10.10 have finally been released for both Google Play Store and F-Droid. Many people were eagerly waiting for a new Conversations build on F-Droid as there were some issues regarding the usage of WebRTC libraries, for Audio/Video calls. F-Droid users were still on the build but now, after 5 months of waiting, they are using the latest version. These releases improve interactions with Bluetooth output devices so be sure to grant the permission as needed. A note for users, the F-Droid version uses an incompatible WebRTC library, so it’s better to switch to the Cheogram app (a fork from the developers) at the moment. The Play Store version does not have this issue.

Moxxyv2 0.2.0, 0.2.1, 0.2.2, 0.2.3 have been released. A new XMPP client for the Android community is featured in this month’s newsletter; it is currently only in the alpha stage. However, the future of the project appears to be pretty promising, and we are pleased to have another XMPP project join the community! The initial version (0.2.0) was made available on July 29th, and the second version (0.2.1) was made available on August 14th. This project is the successor of moxxyv1, which was written in React Native and abandoned due to various technical issues.

Psi+ 1.5.1639 (2022-08-17) has been released.

Tigase released BeagleIM 5.3 (macOS) and SiskimIM7.3 (iOS) which contain changes and stability improvements. Note that SiskinIM will need at least iOS 13 from now on.


Openfire 4.7.3 has been released, which brings many bug fixes, especially for BOSH.


libstrophe 0.12.2 has been released.

Mellium XMPP 0.21.3 has been released.

python-nbxmpp 3.2.0 and 3.2.1 have been released, which bring support for Extensible SASL Profile (XEP-0388) and bug fixes.

Tigase Martin 3.2.1 has been released.

From the ignite realtime community:

  • REST API Openfire plugin 1.9.0 and 1.9.1 has been released to fix several bugs.
  • Openfire ThreadDump plugin 1.1.0 has been released and add two new evaluators for the TaskEngine and statistics from the database connection pool.

Extensions and specifications

Developers and other standards experts from around the world collaborate on these extensions, developing new specifications for emerging practices, and refining existing ways of doing things. Proposed by anybody, the particularly successful ones end up as Final or Active - depending on their type - while others are carefully archived as Deferred. This life cycle is described in XEP-0001, which contains the formal and canonical definitions for the types, states, and processes. Read more about the standards process. Communication around Standards and Extensions happens in the Standards Mailing List (online archive). features a page about XMPP RFCs as well.


The XEP development process starts by writing up an idea and submitting it to the XMPP Editor. Within two weeks, the Council decides whether to accept this proposal as an Experimental XEP.

  • No XEPs proposed this month.


  • Version 0.1.0 of XEP-0469 (Bookmark Pinning)
    • This document defines an XMPP protocol extension to allow users to pin PEP Native Bookmarks.
  • Version 0.1.0 of XEP-0470 (Pubsub Attachments)
    • This specification provides a way to attach elements to a pubsub item.


If an experimental XEP is not updated for more than twelve months, it will be moved off Experimental to Deferred. If there is another update, it will put the XEP back onto Experimental.

  • No XEPs deferred this month.


  • Version 0.2.0 of XEP-0447 (Stateless file sharing)
    • Add disposition attribute to signal when inlining is desired. (lmw)
  • Version 0.2.0 of XEP-0470 (Pubsub Attachments)
    • Update reactions to be similar to Message Reactions (XEP-0444)
    • Namespace bump (jp)
  • Version 1.1 of XEP-0231 (Bits of Binary)
    • Mention where to get textual names of hash functions. (ssw)
  • Version 0.3.0 of XEP-0440 (SASL Channel-Binding Type Capability)
    • Make implementation of tls-server-end-point a MUST for servers. (tm)
  • Version 0.2.0 of XEP-0446 (File metadata element)
    • Use height/width instead of dimensions (lmw)
  • Version 0.2.0 of XEP-0448 (Encryption for stateless file sharing)
    • Replace the ProtoXEP reference with a reference to the published XEP.
    • Add urn:xmpp:ciphers:aes-256-cbc-pkcs7:0 (same as used in XEP-0384) (lmw)

Last Call

Last calls are issued once everyone seems satisfied with the current XEP status. After the Council decides whether the XEP seems ready, the XMPP Editor issues a Last Call for comments. The feedback gathered during the Last Call help improving the XEP before returning it to the Council for advancement to Stable.

  • No Last Call this month.


  • Version 1.0.0 of XEP-0215 (External Service Discovery)
    • Accept as Stable as per Council Vote from 2022-08-03. (XEP Editor (jsc))


  • No XEP deprecated this month.

Call for Experience

A Call For Experience - like a Last Call, is an explicit call for comments, but in this case it’s mostly directed at people who’ve implemented, and ideally deployed, the specification. The Council then votes to move it to Final.

  • No Call for Experience this month.

Spread the news!

Please share the news on other networks:

Subscribe to the monthly XMPP newsletter

Also check out our RSS Feed!

Looking for job offers or want to hire a professional consultant for your XMPP project? Visit our XMPP job board.

Help us to build the newsletter

This XMPP Newsletter is produced collaboratively by the XMPP community. Therefore, we would like to thank Adrien Bourmault (neox), anubis, Anoxinon e.V., Benoît Sibaud, cpm, daimonduff, emus, Gooya, Holger, IM, Ludovic Bocquet, martin, MattJ, MSavoritias (fae,ve), nicfab, Pierre Jarillon, Sam Whited, TheCoffeMaker, wh0nix, vanitasvitae, wurstsalat, Zash for their support and help in creation, review, translation and deployment. Many thanks to all contributors and their continuous support!

Each month’s newsletter issue is drafted in this simple pad. At the end of each month, the pad’s content is merged into the XSF Github repository. We are always happy to welcome contributors. Do not hesitate to join the discussion in our Comm-Team group chat (MUC) and thereby help us sustain this as a community effort. You have a project and want to spread the news? Please consider sharing your news or events here, and promote it to a large audience.

Tasks we do on a regular basis:

  • gathering news in the XMPP universe
  • short summaries of news and events
  • summary of the monthly communication on extensions (XEPs)
  • review of the newsletter draft
  • preparation of media images
  • translations


This newsletter is published under CC BY-SA license.

September 07, 2022 00:00

September 03, 2022


Encrypted Audio and Video Calls

OMEMO logo

Kaidan will receive a grant by NLnet for adding encrypted audio and video calls.

The calls will be end-to-end encrypted and authenticated via OMEMO. Furthermore, Kaidan will support small group calls. We strive for interoperability between Kaidan and other XMPP apps supporting calls. In order to achieve that, we will implement a large number of XEPs (XMPP Extension Protocols). They make it possible to have a modern call experience.

Calls have become more widespread over the past few years in free XMPP chat apps. Especially, grants by NLnet made that possible. The development speed and interoperability between different apps have increased. Such an intense development often results in improved specifications. But sometimes the development overtakes the standardization. In that case, the standardization needs to catch up what has already been implemented.

We have to handle that circumstance with group calls and invitations to calls at the moment. There are some adjustments that are not yet official. To make calls from Kaidan to other apps already supporting them, we have to base our work on those changes. If those unofficial adjustments are being modified later to become official, we will need to modify Kaidan as well. But we see the evolution of calls in XMPP as a huge progress and are ready for adaption!

Kaidan’s goal is to establish free and secure communication while being easy to use, thus lowering the entry barrier to XMPP for average users coming from other networks. NLnet and a couple of other organizations support us via the NGI Zero PET fund to achieve that. The money is provided by the European Commission. That is an example of how software can be developed according to the Public Money, Public Code initiative.

There are many other interesting projects currently funded by NLnet. We are glad that Kaidan is one of them!

September 03, 2022 10:00

September 01, 2022

Paul Schaub

Creating a Web-of-Trust Implementation: Accessing Certificate Stores

Currently, I am working on a Web-of-Trust implementation for the OpenPGP library PGPainless. This work is being funded by the awesome NLnet foundation through NGI Assure. Check them out! NGI Assure is made possible with financial support from the European Commission’s Next Generation Internet programme.

NGI Assure

In this post, I will outline some progress I made towards a full WoT implementation. The current milestone entails integrating certificate stores more closely with the core API.

On most systems, OpenPGP certificates (public keys) are typically stored and managed by GnuPGs internal key store. The downside of this approach is, that applications that want to make use of OpenPGP either need to depend on GnuPG, or are required to manage their very own exclusive certificate store. The latter approach, which e.g. Thunderbird is taking, leads to a situation where there are multiple certificate stores with different contents. Your GnuPG certificate store might contain Bobs certificate, while the Thunderbird store does not. This is confusing for users, as they now have to manage two places with OpenPGP certificates.

There is a proposal for a Shared PGP Certificate Directory nicknamed “pgp.cert.d” which aims to solve this issue by specifying a shared, maildir-like directory for OpenPGP certificates. This directory serves as a single source for all OpenPGP certificates a user might have to deal with. Being well-defined through the standards draft means different applications can access the certificate store without being locked into a single OpenPGP backend.

Since the Web-of-Trust also requires a certificate store of some kind to work on, I thought that pgp.cert.d might be the ideal candidate to implement. During the past months I reworked my existing implementation to allow for different storage backends and defined an abstraction layer for generalized certificate stores (not only pgp.cert.d). This abstraction layer was integrated with PGPainless to allow encryption and verification operations to request certificates from a store. Let me introduce the different components in more detail:

The library pgp-cert-d-java contains an implementation of the pgp.cert.d specification. It provides an API for applications to store and fetch certificates to and from the pgp.cert.d directory. The task of parsing the certificate material was delegated to the consumer application, so the library is independent from OpenPGP backends.

The library pgp-certificate-store defines an abstraction layer above pgp-cert-d-java. It contains interfaces for a general OpenPGP certificate store. Implementations of this interface could for example access GnuPGs certificate store, since the interface does not make assumptions about how the certificates are stored. Inside pgp-cert-d-java, there is an adapter class that adapts the PGPCertificateDirectory class to the PGPCertificateStore interface.

The pgpainless-cert-d module provides certificate parsing functionality using pgpainless-core. It further provides a factory class to instantiate PGPainless-backed instances of the PGPCertificateDirectory interface (both file-based, as well as in-memory directories).

Lastly, the pgpainless-cert-d-cli application is a command line tool to demonstrate the pgp.cert.d functionality. It can be used to manage the certificate directory by inserting and fetching certificates:

$ pgpainless-cert-d-cli help
Store and manage public OpenPGP certificates
Usage: certificate-store [-s=DIRECTORY] [COMMAND]

  -s, --store=DIRECTORY   Overwrite the default certificate directory path

  help    Display the help text for a subcommand
  export  Export all certificates in the store to Standard Output
  insert  Insert or update a certificate
  import  Import certificates into the store from Standard Input
  get     Retrieve certificates from the store
  setup   Setup a new certificate directory
  list    List all certificates in the directory
  find    Lookup primary certificate fingerprints by subkey ids or fingerprints
Powered by picocli

Now let’s see how the certificate store can integrate with PGPainless:

Firstly, let’s set up a pgp.cert.d using pgpainless-cert-d-cli:

$ pgpainless-cert-d-cli setup

This command initializes the certificate directory in .local/share/pgp.cert.d/ and creates a trust-root key with the displayed fingerprint. This trust-root currently is not of use, but eventually we will use it as the root of trust in the Web-of-Trust.

Just for fun, let’s import our OpenPGP certificates from GnuPG into the pgp.cert.d:

$ gpg --export --armor | pgpainless-cert-d-cli import

The first part of the command exports all public keys from GnuPG, while the second part imports them into the pgp.cert.d directory.

We can now access those certificates like this:

$ pgpainless-cert-d-cli get -a 7F9116FEA90A5983936C7CFAA027DB2F3E1E118A
Version: PGPainless
Comment: 7F91 16FE A90A 5983 936C  7CFA A027 DB2F 3E1E 118A
Comment: Paul Schaub <>
Comment: 2 further identities


Would this certificate change over time, e.g. because someone signs it and sends me an updated copy, I could merge the new signatures into the store by simply inserting the updated certificate again:

pgpainless-cert-d-cli insert < update.asc

Now, I said earlier that the benefit of the pgp.cert.d draft was that applications could access the certificate store without the need to rely on a certain backend. Let me demonstrate this by showing how to access my certificate within a Java application without the need to use pgpainless-cert-d-cli.

First, let’s write a small piece of code which encrypts a message to my certificate:

// Setup the store
SubkeyLookupFactory lookupFactory = new DatabaseSubkeyLookupFactory();
PGPCertificateDirectory pgpCertD = PGPainlessCertD.fileBased(lookupFactory);
PGPCertificateStoreAdapter store = new PGPCertificateStoreAdapter(pgpCertD);

OpenPgpFingerprint myCert = OpenPgpFingerprint.parse("7F9116FEA90A5983936C7CFAA027DB2F3E1E118A");

ByteArrayInputStream plaintext = new ByteArrayInputStream("Hello, World! This message is encrypted using a cert from a store!".getBytes());
ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream();

// Encrypt
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign()
      .addRecipient(adapter, myCert)));
Streams.pipeAll(plaintext, encryptionStream);


In this example, we first set up access to the shared certificate directory. For that we need a method to look up certificates by subkey-ids. In this case this is done through an SQLite database. Next, we instantiate a PGPCertificateDirectory object, which we then wrap in a PGPCertificateStoreAdapter to make it usable within PGPainless.

Next, we only need to know our certificates fingerprint in order to instruct PGPainless to encrypt a message to it. Lastly, we print out the encrypted message.

In the future, once the Web-of-Trust is implemented, it should be possible to pass in the recipients email address instead of the fingerprint. The WoT would then find trustworthy keys with that email address and select those for encryption. Right now though, the user still has to identify trustworthy keys of recipients themselves still.

Similarly, we can use a certificate store when verifying a signed message:

ByteArrayInputStream ciphertextIn = ...; // signed message
ByteArrayOutputStream plaintextOut = new ByteArrayOutputStream();

// Verify
DecryptionStream verificationStream = PGPainless.decryptAndOrVerify()
  .withOptions(new ConsumerOptions()
Streams.pipeAll(verificationStream, plaintextOut);

OpenPgpMetadata result = decryptionStream.getResult();
assertTrue(result.isVerified()); // signature is correct and valid

Here, PGPainless will process the signed message, identify the key that was used for signing and fetch its certificate from the certificate store.

Note, that if you implement verification like that, it is up to you to verify the trustworthiness of the certificate yourself.

In the future, this task will be done by a WoT library in the PGPainless ecosystem automatically though 🙂

The current state of the certificate store integration into PGPainless can be found on the storeIntegration branch.

by vanitasvitae at September 01, 2022 11:19

August 31, 2022

Ignite Realtime Blog

Openfire ThreadDump plugin 1.1.0 released

Earlier today, we have released version 1.1.0 of the Openfire Thread Dump plugin. This plugin uses various evaluators to trigger the creation of a Java thread dump. These thread dumps provide valuable information that is typically used when analyzing issues within Openfire’s implementation.

In the new version of the plugin, two new evaluators have been added: one that looks at the usage pattern of Openfire’s TaskEngine, and another one that uses statistics from the database connection pool.

The updated plugin should become available for download in your Openfire admin console in the course of the next few hours. Alternatively, you can download the plugin directly, from the plugin’s archive page.

For other release announcements and news follow us on Twitter

1 post - 1 participant

Read full topic

by guus at August 31, 2022 14:22


Kaidan's End-to-End Encryption Trust Management

We worked several months on Kaidan’s upcoming end-to-end encryption and trust management. Once Kaidan 0.9 is released, it will provide the latest OMEMO Encryption. But it will also make trust decisions in the background for you if it’s possible. Some trust decisions have to be made manually but there are many others Kaidan automates without decreasing your security. That is done by automatically sharing trust decisions via already secured channels.

The feature Kaidan uses is called Automatic Trust Management (ATM). Your device receives the encryption data to secure the conversation between you and your contact via the internet. That encryption data can be the data of an attacker. While you think that you communicate with your contact securely, the attacker can read, modify or drop everything you exchange.

You have to make sure that the encryption data you received are really those from your contact to detect and stop an attack. That is done by comparing the exchanged encryption data via a second secure channel. Kaidan provides QR codes for that. QR codes are especially helpful when you want a secure conversation with a contact you can meet in person. For that, you simply scan your contact’s QR code and vice versa.

First QR code scan

Second QR code scan

But what if your contact used a smartphone during the first QR code scan and now wants to chat with you via a notebook too? Usually, your contact would have to scan the notebook’s QR code with the smartphone and vice versa. Furthermore, you would have to scan the notebook’s QR code and vice versa. If you or your contact gets another device or even replaces an old one, QR codes have to be scanned again. That leads to multiple mutual scans, one for each pair of devices.

In the following example graph, there are four devices. B1, B2 and B3 could be your contact’s devices and A1 yours. The six gray edges are the mutual QR code scans that are needed to stop all possible attacks.

Needed trust decisions

With ATM, many QR code scans between you and your contact become unnecessary. The first meeting is used for the initial scan. The encryption data of all new devices is checked via the secure channel established by it. If your contact wants to chat via the notebook, your contact simply scans the notebook via the smartphone and vice versa. But all other scans are not needed anymore. The trust decisions are communicated between the devices that already have a secure channel.

In the example graph, ATM could work as follows:

  1. A1 scans B1’s QR code and vice versa.
  2. A1 scans A2’s QR code and vice versa.
  3. A2 scans A3’s QR code and vice versa.
  4. The remaining three edges are created automatically by ATM via the existing secure channels.

If you want to try out that new feature, stay tuned! Our next release will come soon.

August 31, 2022 10:00

August 30, 2022


Signup with Cheogram Android

Welcome to! If you are looking for a simple guide on how to sign up for JMP, then you have come to the right place! We will be keeping this guide up-to-date if there is ever a change in how to sign up.

We will first start with signing up from within your Jabber chat application on mobile, where you will never need to leave the client to get set up. I will be using the freedomware Android client Cheogram to do this signup. To start us off, we will need to create a Jabber ID (or “JID”). Upon first opening the app you will be presented with a welcome screen where you can choose to signup using the built-in flow for or, or you can choose your own custom server.

Main Startup Screen Jabber Server Selection Account User Creation

We will choose for the purposes of this guide, but you are definitely free to choose whatever service you like, or bring your own! On the first screen of the server signup it will ask you to enter a username; this can be anything you want as long as it isn’t already in use on the server. After tapping Next, it will ask you to create a password for this account; length does not seem to be limited so create one as long as you want. Do not forget it, or use a password manager to create/store the password! Tapping Next again will log you in and offer to set an avatar for your account, you can set one now or choose to do so at a later time, if at all. Once logged in to the new account, Cheogram will ask for permissions to your contacts, you can accept or deny them. Accepting will allow us to implement the integration, which we will explain at the end of this post.

Password Creation Profile Avatar Main Chat Captcha Contacts Permissions Dialog

Now the fun begins! First we will need to add the Cheogram bot as a contact before communicating with it. To do this tap the “chat” bubble icon in the lower right corner, it will change views as well as change to a “+” sign, tap it again, then tap “Add contact”. A dialog box will appear where you can type in a contact’s “Jabber ID”, here you will want to put and tap Add, it will provide a prompt saying that it “appears to be a domain”, so tap “add anyway” and then it will open the screen for the bot, most likely displaying the bot comands tab view.

Chat Icon Press Add Contact Dialog Bot Commands Tab View

From here you will get to see one of the features of the Cheogram app, the Command UI! When a chat first opens you will notice that a “tab” near the top will appear titled “Commands”; it is from within this tab that you can manage all the features and settings of your JMP account, but first we need to register an account, and you will notice there is only one command available right now, “register with backend”. You will want to tap this “register” command, and it will take you to the next step. Here you will choose the backend SGX you are wanting to use; this list includes the most popular community ones as well, but we need to select the JMP option. The next screen will ask you to enter a search term for selecting a number; this can be by area code, state/province, city&state/province, or lead with the tilde “~” character to indicate a vanity pattern. We have chosen areacode 902 which then shows us a list of numbers on the next screen; choose one and tap Next.

Backend Selection Number Search Box Number Selection List

On the following screen it will ask you how you wish to activate your account; you have four options: Credit Card, Invite Code, Bitcoin, and Mail or Interac e-Transfer, as well as what the base currency is that you want to use. For this tutorial we have chosen credit card and Canadian dollars. Tapping Next will give us a page rendered in-app where you can add a credit card to use for activation, and choose the amount of funds that will be auto-charged to your credit card when your balance drops below $5. If you clear this box before tapping save, it will disable the auto top-up feature on your account, tapping Next will finish the sign up process. You can now open the Commands tab again and check out the new commands available for your account; details on these commands will come in a seperate blog post.

Currency and Payment Option Invite Code Activation Screen

Now that you have activated your account you are able to call (who really does this anymore, seriously? ;) ), SMS or MMS with your contacts. To add a contact within Cheogram is quite easy with the contacts integration. Now that the bot has been added to your account contacts, your device’s contacts should already be visible when you tap on the “chat” icon to start a new chat, or you can do the following to add a contact to your Jabber server. First tap the chat icon again like you did earlier to add the bot, tap the “+”, then “add contact”. The first thing you should notice that is different this time with the dialog box that pops up is that it now has two selectable buttons: Jabber ID, and PSTN. The PSTN option makes adding telephone numbers for calling or sending SMS to very easy, just type out the phone number you wish to add to your contacts and then tap ADD. This will automatically format the phone number according to the locale detected on your device. If you need to add an international number, you will need to add the phone in the full international format to override the country code being automatically added. With the contact now added, you can either start typing out a message, or tap the “phone” icon that appears at the top to make an audio call to the contact. Images, videos and audio files can also be sent using a number from JMP.

Bot Commands PSTN Contact Dialog Conversation View

Another helpful feature of the Cheogram app is native dialer integration. This allows you to make phone calls straight from your dialer just like any other phone call. To enable this, tap on the 3-dot menu in the top right of the main Cheogram screen, and then tap on Manage Accounts. Here you should see a new option under your account(s) that says “Manage Phone Accounts”, tap on that title and it will take you to a system settings page where you can enable your Jabber ID to make and receive calls, tap the toggle next to the account you want to enable. Now go back to your Manage Accounts screen in Cheogram and then tap the “gear” icon and from this second system settings page, you can select which “calling account” is your default, or to require it to always ask what account you want to use. Do note that there is currently a known bug in Android where this setting will reset after every reboot of the device, there currenltly is no fix out and Google says it will be fixed in a later release version of Android.

Manage Accounts Screen System Dialing Accounts Default Dialling Accounts

by Root at August 30, 2022 02:09

August 25, 2022

Erlang Solutions

Implementing Go Fish to Learn Elixir

A walkthrough of how we implemented GoFish as a way of learning Elixir and the concepts of the BEAM and OTP.


In this article, we will outline our initial design and implementation of the card game Go Fish in Elixir using raw processes, and then describe how we were motivated to re-implement the project using the GenServer module instead. The first step is to agree upon the rules of the game, then describe the domain model and non-functional requirements, and from these we can design the solution using sequence diagrams for various scenarios.

Based on this design, we then implement it in code. We are using Test Driven Development, meaning we start by writing a failing test and then make it pass by implementing the code for it. This approach reduces debugging times and encourages clean and simple code solutions.

It’s important to note that, while this blog post is presented in a logical order, in reality, we arrived at the eventual solution iteratively. For example, several sequence diagrams have been discarded to reach the ones we present here.

Go Fish rules

These are the rules we will follow. This description takes basis in the description on Wikipedia.

Five cards are dealt from a standard 52-card deck to each player, or seven cards if there are only two players. The remaining cards are shared between the players, usually spread out in a disorderly pile referred to as the “ocean.”

The player whose turn it is to play asks another player for their cards of a particular face value. For example, Alice may ask, “Bob, do you have any threes?” Alice must have at least one card of the number she is requesting. Bob must give Alice all cards of that number in his hand. If he has none, Bob tells Alice to “go fish,” and Alice draws a card from the “ocean” and places it in her own hand. Then it is Bob’s turn, since the turn switches to the person saying “go fish.” When any player at any time has four cards of one face value, it forms a book, and the cards must be placed face up in front of that player. When all sets of cards have been laid down in books, the game ends. The player with the most books wins.


An overview is shown in the domain diagram below.

  • The Ocean initially holds all the cards in the deck.
  • When a Player collect Cards from the Ocean this is called “going fishing”.
  • A Book is formed by 4 cards of the same value.


We need to make a playable version of the Go Fish game. This implies the following functional requirements:

  • A player can join a game.
  • A player can ask another player for cards of a specific value so that they can collect cards from that player’s hand, or else go fishing.
  • A player can draw cards from the ocean.
  • A player can form books out of four cards of the same value in their hand.
  • Once all books have been collected, a winner will be determined.
  • Non-functional requirements
  • The game should be playable by calling the external API for each process in the BEAM.
  • Another process must call the external API of other processes and cannot send messages directly to the process.


First of all, we need a process for the Ocean that can hold cards. Other processes should be able to draw cards from that Ocean.

Then we need a process for each Player, each player has a set of books and cards.

We will have a Controller, which will keep track of the players that are in the game, whether the game is over, and who won the game.

Before we start coding, we draw sequence diagrams to determine what messages are sent throughout a game. Our initial design wasn’t perfect, and we had to go back and update the sequence diagrams when we realized that certain things needed to change. For example, initially, we had planned to implement a fully-distributed approach, with only the Player and Ocean entities, however, this turned out to over-complicate the process of determining when the game is over and who had won. So in the end we added a Controller to keep track of this. This resulted in the following sequence diagram (illustrating a two-player game).

This diagram describes the game start-up, where new players (John and Simon) first register their names with the Controller. Both players draw 7 cards from the Ocean. Games with 3 or more players draw 5 cards each. Gameplay can now begin with the first player (John) requesting any 3s from the second player (Simon). John receives a card from Simon, and so his turn continues. His second request, for 4s however, is met with a “go fish,” as Simon does not have any 4s. The turn has now passed to Simon; however, John must first take a card from the Ocean. He receives a 3 of hearts, which completes his “book” of 3s. He then sends a message to the Controller that a new book has been made.

Play continues in this way until the Controller has counted that 12 books have been made. When the 13th book is made, the Controller sends stop messages to each player and the Ocean, and calculates the winner, based on the player with the most books.

From raw processes to GenServer

Processes can send and receive messages. They act depending on the message received. We can see that in the initial implementation of the Player process. To maintain the state within this process, we pass the state as a parameter to the recursive call. In this case, the state consists of a hand of cards.

defmodule GoFish.Player do
  defp loop(hand) do
    IO.puts(["Player has the hand: ",hand])
      :go_fish ->
      {:cards, cards} ->
        loop(cards ++ hand)
      {:give_me_all_your, taker, asking_value} ->
        #TODO ...

As you can see, the receive loop will quickly grow for every message we need to receive. We will also have to come up with receive messages for every synchronous call. Finally if one of the processes in the game fails, we currently have no mechanism for recovering the game. The solution to these issues is to use GenServer.

One immediate benefit of GenServer its easy implementation. This is partly due to the concise introduction in the documentation that includes clear examples to get started using it. As documentation can sometimes be a little difficult to follow, this was a real help.

GenServer abstracts away the loop function and allows us to organise what happens on each receive message into functions, eliminating some boilerplate code and improving readability.

GenServer makes it easier to send synchronous messages (call), since we don’t need to implement the receive call for getting a response back from send message.

GenServer can be organised into a supervision tree, which makes it possible to monitor all processes in the game and restart them once one of the processes dies using a recovery strategy. For Go Fish we used the “all for one” supervision strategy, meaning that once the supervisor detects that a child process has died, it will restart every other child process. We chose this strategy because if the player or ocean process dies, the entire game will need to be restarted.


As indicated previously, we used Test Driven Development (TDD) approach. We sought to first and foremost test individual functions isolated from their use in processes. Then we added tests for processes for which there are certain quirks. However there were some hiccups along the way.

We found that using spawn or start_link for a named process would cause the error that a process with the same name had already been registered. This was because the processes weren’t terminated at the end of each test. Later we found that this could be resolved by using the start_supervised function instead, which would take care of starting and terminating the processes for each test.

But then we inserted it into the ExUnit.setup_all block, which we mistakingly thought would be executed before every test, but then we found that we needed to use ExUnit.setup for that. We found the naming to be unintuitive, which again shows that naming things is one of the hardest problems in computer science.

TDD made it clear what the intended functionality was and allowed us to focus merely on that feature without getting distracted by other things that could be improved. For these, we simply wrote a #TODO comment such that we could revisit it later.

Discussion & Conclusion

Implementing a game as the first introduction to a language is a great way to get started. It allowed us to focus all our energy on the new concepts and syntax since the specification for the game was very clear and relatable. Go Fish was a good fit for learning BEAM since it naturally mapped to multiple processes that communicate with each other.

Pair programming was very helpful in getting through challenging problems and for sharing editor workflows and shortcuts with each other. A future blog post may go into depth on pair-programing in a remote setting.

Want to learn Elixir?

We’re proud champions of Elixir. To help further the adoption of Elixir throughout industry and developer communities we offer a wide range of training. From bespoke corporate training to beginner training for individuals, there is likely a course for you. Find out more at our training page.


Go Fish – Wikipedia

GenServer – Docs

ExUnit – Docs

Our Go Fish implementation – GitHub

Simon El Nahas: BlogTwitterGitHub

Thanks to the following great people for reading drafts and providing comments on this:

Tee Teoh – Erlang/Elixir Architect

Torben Hoffmann – VP of ESL London

Alex Koutmos – Author – Twitter

The post Implementing Go Fish to Learn Elixir appeared first on Erlang Solutions.

by Simon El Nahas and John Holt at August 25, 2022 09:00

August 23, 2022


Newsletter: New Employee, Command UI, JMP SIM Card, Multi-account Billing

Hi everyone!

Welcome to the latest edition of your pseudo-monthly JMP update!

In case it’s been a while since you checked out JMP, here’s a refresher: JMP lets you send and receive text and picture messages (and calls) through a real phone number right from your computer, tablet, phone, or anything else that has a Jabber client.  Among other things, JMP has these features: Your phone number on every device; Multiple phone numbers, one app; Free as in Freedom; Share one number with multiple people.

This month sees the addition of a new member to the team, you will see him in the chat as seki.  Seki joins us as a software developer and general team member, be sure to say hi!

Cheogram Android 2.10.9-1 has been released.  This release includes a major new feature: the Command UI.  The best place to see this feature is when talking to the bot at  You will see a new tab labelled “Commands” that lets you interact with the bot using a nice UI instead of by sending specially-formatted chats.  This release also includes several fixes to URI display and copying, and is based on Conversations 2.10.9 upstream.  We have added a long-press menu on the list of all active conversations to perform quick actions (such as “pin to top”), added support for muting yourself from the dialler integration, changed the ringback sound to be more familiar to USA and Canada users, and various other small bugfixes.

JMP is actively working on providing cost-effective data-only eSIMs and SIM cards for users.  Pricing is not yet final, and there is some work to do before this is ready for the general public, but if you are interested please sign up for the wait list at the link above.  Our first launch will be with USA and Canada coverage, but other areas are possible in the future if there is interest.

This month we are also pleased to announce the launch of multi-account billing.  This feature allows customers to have one account be billed for all their JMP accounts, or those of their family.  To get started with this, please contact support and indicate the accounts that you want linked together.

To learn what’s happening with JMP between newsletters, here are some ways you can find out:

Thanks for reading and have a wonderful rest of your week!

by Stephen Paul Weber at August 23, 2022 18:46

August 22, 2022

Erlang Solutions

How Can Technology Answer the Questions Still Unanswered in FinTech?

Leaders in the fintech industry joined us to discuss how technology can answer the remaining questions in fintech. They explored key technologies shaping the sector that could also have an impact on society as a whole. Join our panel moderated by Andrew Vorster (Innovation Catalyst) featuring Jacky Uys (Mambu), Chris Skinner (The Finanser and author), and Genevieve  Leveille (CEO & Founder of  AgriLedger), and Ritesh Jain (Fintech Founder & Advisor).

Which are the unanswered questions in FinTech?

Andrew Vorster: Good evening, everybody. So, thank you very much for coming here. This is going to probably be the most irreverent panel you’ve heard for a while, and the reason is, that I’m going to run it a little bit differently from a normal panel. You see, when I was told about this panel, “How Can Technology Answer the Questions Still Unanswered in FinTech?” I incorrectly thought that I was going to be invited to sit on the panel. And I thought, “Well, this is going to be the quickest answer ever, and I was going to say, “It can’t.” And then, they went, “No. We want you to moderate the panel.” And I thought, “Oh, oh, this is going to be a lot tougher now.”

So how can I make my life easy? See, if you want the most efficient way to do something, give it to a lazy person. Well, I’m a lazy person. I always find shortcuts. So, I had a chat with these people, and I’m not letting them introduce themselves at all, because actually, they’re not representing their companies. They’re here because they’re really smart and they have opinions. So if you want to know who they are, I’m afraid you’re just going to have to have a look at the agenda because I’m not letting them talk about themselves at all. They’re going to be talking about the topic of how can technology answer the questions still unanswered in FinTech.

So I thought, the quickest way of me doing that was for them to tell me what the unanswered questions in FinTech are because I don’t know what they are and I’m too blooming lazy to try and figure them out. I’m going to play a bit of “Jeopardy!” Are you guys familiar with the way that “Jeopardy!” works, the game show? No? Oh, jeez, I was just checking that you were alive there.

It’s American, but we’ve seen a bit of pop culture and that kind of thing. So in “Jeopardy!” the host gives the answer and the guests have to give the question. And I went, “Oh, this is brilliant,” because we’ve all got all these FinTech trends and buzzwords flying around that Erlang has done a whole FinTech trends report. So I just opened that up and I went, “Buzzword, buzzword, buzzword, buzzword, buzzword.” I went, “Great. These are all the answers. What the hell are the questions?” What are the unanswered questions that they’re solving? What are these things doing?

So I thought, “Okay. I’m going to play some ‘Jeopardy!’ with the panel here.” So, they’re going to have to improvise because we haven’t got any technology to support this panel. So they haven’t got buzzers. The first thing they’re improvising on is they’re going to have to make a buzzer sound up to answer. That’s going to be the first thing. I said it’s going to be a little bit irreverent, right?

Andrew Vorster: So, Chris, obviously you’ve got an answer…oh, a question at least, right? What’s the question? What is the unanswered question in FinTech that blockchain is the answer for?

Chris Skinner: What’s been the biggest failure in technology?

Andrew Vorster: Okay. Do you wanna expand on that before I hand that to Genevieve Leveille because she’s challenging you…right?

Chris Skinner: It’s just that, how many live production mainstream systems on the blockchain are there out there? I don’t see that many. And yet everyone is buzzing saying there’s going to be loads by… well, 2020 they were saying. It’s now 2022 and there are still hardly any.

Andrew Vorster: So you can’t think of any valid use cases for blockchain then?

Chris Skinner: I can think of loads, but they’re nearly always involving governments and industries and financial institutions and corporates having to work together to agree on common standards, and they can’t agree on any standards. So the technology itself is a great idea, but it’s a solution looking for a problem that can be solved, and the problem can’t be solved because no one can agree on anything.

Andrew Vorster: Interesting. Genevieve Leveille, what’s your take

Genevieve Leveille: I think it’s because you’re asking for agreement rather than consensus. The challenge I would have is the technology, the way we implement technology is more about how much can you make from it, rather than how can I build it for the people who need to use it. And that has been the failure I would say right now, where we are building solutions, as you say, for problems that are not exactly the way people want. This technology is about collaboration. So unless you can collaborate, you might as well put it aside.

But also, I think that the other premise has been that this is about deseating people. “I’m going to get rid of the government, I’m going to get rid of banking, I’m going to rid, rid, rid,” when in reality, it’s about creating that responsibility, accountability, and consulting or informing. And until you start putting those things in, you’re not going to solve it with the technology. So agree and disagree.

Jacky Uys: My question is how secure is the data?

Andrew Vorster: How secure is the data?

Jacky Uys: Is it that secure in the block? 

Andrew Vorster: Interesting. And what’s your answer to that?

Jacky Uys: I think it’s not very secure. I think it’s the only value proposition for the blockchain. I think they’re making too much of the data, data sovereignty. But I think there’s a lot more to blockchain than just data. So for me, it is what you’re going to do with the data.

Genevieve Leveille: You can do a lot with the data.

Blockchain applied at AgriLedger

Andrew Vorster: And AgriLedger is actually…a little bit of an opportunity to plug what you guys do that…

Genevieve Leveille: I wasn’t going to…

Andrew Vorster: And I know you weren’t…

Andrew Vorster: Can you just expand to the audience about what you guys have been doing?

Genevieve Leveille: Sure. What we’ve been doing is we’ve started the process of really working with the smallholder farmers, those people who are at the bottom, in what I would call the first mile. So the question is why blockchain? Well, because if you were to put the information onto a central database, the person who’s going to take care of it is going to be either a government or a company, which means that they can modify things. So it’s about creating trust across the value chain. And this is not a supply chain. It is a value chain. And as things grow… this is why the data is important.

One of the things that you said, which is very much on my radar, is confidential computing. How do you now… Because what people don’t realize is when it goes from node to node, the security is no longer there, if the data is open, so we need to create those things. And I would suggest that there is an opportunity. We’re probably about three to five years. And to answer your question, 2020 to 2022 has been a write-off.

Chris Skinner: I know quite a lot of FinTech startups that started in 2020 and they’ve been doing very well. It’s not a write-off because we’ve all been Zooming and connecting. That’s not the same as meeting, but you can still develop blockchain solutions remotely.

Genevieve Leveille: We delivered it remotely because we couldn’t go to Haiti because there was a lockdown before 2019 was lockdown. So we delivered it by training people over Zoom.

Chris Skinner: I thought you said you couldn’t go to Hades, and I was thinking…

Genevieve Leveille: No, we couldn’t go. We couldn’t go.

Chris Skinner: No, you said Haiti. I thought you said Hades.

Genevieve Leveille: It was hell.

What is the unanswered question in FinTech that blockchain is the answer for?

Andrew Vorster: So what is the unanswered question in FinTech that blockchain is the answer for?

Jacky Uys: Inclusivity. 

Andrew Vorster: Inclusivity?

Jacky Uys: Yes, financial inclusivity.

Chris Skinner: And consensus.

Genevieve Leveille: Digital inclusion.

Andrew Vorster: Consensus?

Genevieve Leveille: Digital inclusion?

Chris Skinner: And provenance, proof.

Chris Skinner: We’re trying to keep you out of it.

Genevieve Leveille: He’s a GBA, you know.

Ritesh Jain: So inclusion I’ve got a question about it. When we say inclusion and digital inclusion, that’s far off, right? Because I don’t see the blockchain is going to solve the inclusion straight away, because that’s an infrastructure problem. And that’s not only in the infrastructure. Unfortunately, when we talk about inclusion, right, you need to consider not only the financial digital exclusion as a major issue. Let’s not get there in terms of financial inclusion across the world and cashless society and everything else, because that’s a fundamental infrastructure challenge, and more than the infrastructure, that’s a public policy challenge. So what blockchain can solve up to a certain extent, is through identity, right?

So the first thing that needs to be sorted out for inclusion is the identity, and then you move on with anything else.

Genevieve Leveille: I would suggest that my concern is until we look at privacy… So that’s where blockchain right now is not being built with privacy by design. So until we do privacy, I don’t want my digital identity. I might want my footprint to be evident, but I don’t want details about me on the chain.

Andrew Vorster: Let’s just come back to you before we go back to Chris. See, this is working there already.

Jacky Uys: Well, I think for me a great example was the first mouths to feed. Those are the guys that we generally don’t see. We don’t feed those mouths. First, we feed the top of the food chain to the bottom. And I like your approach. It’s bottom-up.

Genevieve Leveille: But the VCs don’t love it very much because I’m trying to break something.

Andrew Vorster: So, Chris, what were you saying about the inclusion?

Chris Skinner: Going back to why I commented on the biggest failure in technology recently, it’s because I just thought… Remember, so many headlines in conferences that I went to, 2015 to 2018 in particular, such as the United Nations in D.C. had a meeting all about identity in 2016 saying that they were going to start rolling out proof of work using blockchain technologies with Microsoft and Accenture for Sustainable Development Goal 16, which is 16.9 as a legal identity for everyone on Planet Earth. It didn’t happen.

Sierra Leone announced they were going to roll out blockchain for digital identity in 2019. It hasn’t happened. The Dubai government announced in 2016 that the whole of Dubai would run on blockchain by 2020. We haven’t seen anything about that.

So, there was all the buzz and the hype, and there’s still a lot of work taking place in the background like yours and others, but it’s just taking so much effort to push the thing uphill.

Genevieve Leveille: So, I think one of the challenges also is it costs a lot to do blockchain, and it’s much easier to continue with what isn’t blockchain. The only thing I take from the thing that will not be named is it pays for itself. So we need to start thinking differently about how things pay. So really, the product paying for itself will be the way of actually creating what is needed in terms of… And I think this is where I’ve sort of been saying what are we doing? FinTech. We talk about financial technology. We look more at the financial rather than the technology. So you’ve seen a lot going on in the blockchain space in terms of fin, so the Defi, all those things happening, but the tech, they haven’t taken care of making sure it was resilient.

Chris Skinner: And the core of that is not how to make the technology pay. It’s how do the people developing these technologies and implementing them make money out of it?

Andrew Vorster: Ritesh, your response was?

Different models for using blockchain/UPI?

Ritesh Jain: So the focus is around what I’ve seen. It’s quite a lot of concentration, right? From what we have seen, there are different models. So again, so I’m going into the broader spectrum. We have seen the U.S. model, the European model, and China, and now I talk about the Indian model as well. And when I’m saying the model, it’s about how you build the infrastructure and this tech in the country I’m referring to the digital public infrastructure. And one of the best examples that you could see is the UPI, right?

Andrew Vorster: Expand, just in case the audience isn’t aware of UPI.

Ritesh Jain: UPI is a unified payment interface. That’s a digital public infrastructure in India to enable payment, digital payments. What we are looking at, we are, as India, leading the world in terms of the number of digital transactions today. In the next couple of years, by 2025, 2026, the expectation is around going to a billion transactions a day.

So the whole idea is around don’t just get bogged down with the regulation. And unfortunately, that’s what I’ve seen across the various models. China’s very straightforward. Regulations, enforced. European, regulation, consensus. U.S., regulation driven by the public rather than privatization, right? The Gulf has the big techs. India, it’s a digital stack build-up, and the public-private partnership builds the product and services around it.

So we need to think and learn from the digital stack model and think from that perspective so that we don’t see the concentration in the market. And if you talk about the concentration over here, we know the Gulf has the big techs, or even in the U.K. for that matter, right? The credit card market is highly concentrated, 5 players own 92% of the market. Financial institutions are highly concentrated, and that’s why the evolution of FinTech or even open banking is important. 

Andrew Vorster: Technology can help to increase competition so long as the regulation and the infrastructure are determined centrally, or at least enforced, to be able to be open. Technology can solve an unanswered question in terms of how we can increase competition to be able to make it fairer access. Easier, quicker, faster? What’s the key? What’s the main benefit of the UPI in India?

Ritesh Jain: So the main benefit of the UPI is the digital payment adoption across the country, right? It has enforced digital inclusion as well as financial inclusion across the country. I will not talk about financial literacy, because that’s a separate challenge. We can talk about that.

Andrew Vorster: We’ll talk about that in a bit.

Ritesh Jain: So it has put India on a different stream in terms of growth. And it’s not only about the UPI. Today, if you look into…from a commerce perspective, e-commerce, the first thing that comes into mind is Amazon, right? Highly cash-liquid company. They can deploy their cash in any market and capture the market. Do we want to continue with that? So what do we do about it? How we can enable our MSMEs and the other merchants to play a part in the economy? You got to build a stack where everybody plays a part and becomes part of it and build an interoperable solution, so that MSME, whether it’s a big player or a small player, they can play around it so you can reduce the market concentration.

So the answer is, don’t wait for the regulation. Thank you for the privacy, right? We don’t need to just wait for privacy. Your infrastructure stack can enforce privacy. And I’m completely on to it, do not wait for the regulation. We have already seen that in the market-driven and the regulatory-driven, whether it’s open banking or the various other products, say buy now, pay later, for that matter.

What’s the unanswered question that buy now, pay later solves? 

Andrew Vorster: That was going to be one of my next buzzwords. So I’ll actually…I’m going to kick that one off because it is… So, buy now, pay later is the answer. What’s the question? What’s the unanswered question that buy now, pay later solves? And apologies to anybody in the audience who is BNPL, but I have got a bad reaction to…

Let’s give Jacky some air time here.

Jacky Uys: The question is can the economies do without retail credit?

Andrew Vorster: And the answer is BNPL. Do you think it’s a good thing or not?

Jacky Uys: Man, I’m going to be subjective. I’m sitting on the fence with this one because I believe, for a certain segment of the market, it’s fit for purpose. And I believe there’s another part of the market where it’s not fit for purpose, because regulation, we haven’t waited for that. So I’m a bit on the fence with that one. Do I consume it myself? I don’t have to. But I do believe there’s a big market out there that potentially could ease the burden in a short term. But I do also think…like, I’m very vocal about my opinion about the mortgage market in Amsterdam or the Netherlands. There’s a bubble and we just don’t know how big it is.

Andrew Vorster: And BNPL?

Jacky Uys: Is a bubble.

Andrew Vorster: You had also beeped for BNPL.

Ritesh Jain: So thank you. BNPL, it’s an interesting proposition, nothing new. We have seen that, been there in the past. It’s like tokenization, right? American Express came with the tokenization very early than its time. But then, Apple Pay came. BNPL was existing in the market, but technology and the channels have reduced the friction across the customer journey. It’s a great product, but, at the same time, it got to be controlled. If you have got access to the customer data at the BNPL, and if you can put friction in the checkout journey and let customers know what they are getting into. And if you can enforce controlled behavior, it’s a great product. Otherwise, we are seeing a debt-ridden society. We are going to see the payday loans.

How can technology help increase financial literacy?

Andrew Vorster: So I’m glad that you said let the customer know, add some friction in. And this won’t be a “Jeopardy!” this will be a straight-up question to you. One of the biggest problems that I see, and I do think that technology can help solve the problem, is financial literacy. People often think of financial literacy as something that’s a problem in other countries. That’s a problem somewhere else. That’s not a problem here where we are in the West, and, you know, we’re all financially literate. Bullshit. I can tell you that the vast majority of people in this country are not financially literate. They don’t understand the consequences of credit, credit cards, long-term, and short-term credit, or investing. Most of them wouldn’t even be able to construct a budget for their own lives, particularly factoring in paying off their credit card debt. And they all get into it. My worry about BNPL is not so much the BNPL, because I think an astute consumer would understand what it means.

But most consumers are not financially literate, and it does get worse when you go into other… So, I’m asking all of you here, and again, buzzers, how can technology help increase financial literacy?

Ritesh Jain: Beep, beep.

Andrew Vorster: You guys better are faster on your buzzers, otherwise, Ritesh Jain is having all the air time.

Ritesh Jain: Let me give you a bit of insight on the financial literacy in this market. We have done deep research in the market survey with a sampling of 18,000 in the U.K. Seventy-eight percent of credit card customers do not know when they make a minimum payment on the card, they incur higher interest rates, 78%.

Andrew Vorster: And that’s in the U.K.?

Ritesh Jain: That’s only in the U.K., and we are a developed country. Seventy-odd percent of people do not put direct debit onto their credit card for XYZ reason and they end up paying late payment charges. In this country, where the market is highly concentrated, 5 players own 92% of the credit card market, outstanding credit card debt was £70-odd bil before the pandemic, which has gone down to £56 bil now, thanks to the pandemic. We got better with the debt.

At the same time, between £5 billion and £6 billion people pay in late payment charges and the higher interest rates on the credit card in this country, 66 million credit cards out of 60 million population, so on average, we hold 2 credit cards per person, a massive challenge. And that’s why I precisely said, the buy now, pay later, it’s a great product. A credit card is one of the best products in financial history. It offers you 30 to 45 days of interest-free credit, but only if you use it the right way. Dynamic credit checks are a must. The credit card you have got a credit limit and you can keep swiping on. Your profile might change but your credit limit won’t. But buy now, pay later, you have got an opportunity to control that. What we need is the bureau data. Today we don’t have that. And likes of TransUnion, which they are forcing into getting all the data from the buy now, pay later companies so that they can do the dynamic checks and look into the credibility in real-time. That’s what is required.

Andrew Vorster: But that’s changing…that’s a transactional thing. My question is, how can we increase financial literacy, not stop their spending? I want to increase financial literacy. But you’ve had air time. I’m going to let Jacky respond to that…

At last, you’ve pressed your buzzer there, Chris.

Jacky Uys: Good point. It’s not… You’re in the U.K., right? But TransUnion in South Africa very much makes its bureau data available to its financial institutions there. And TransUnion led in South Africa in the whole affordability model check. And what they did with that affordability checking working out commit versus, what the income is that actually could give the consumer insights to say, “Listen, you’re completely overcommitted. Therefore, decline.” The client bank declined because this person has already 80% over-commitment, so they’re just living on credit. It’s a very interesting topic. But I do believe that in certain markets, the technology lags versus in others.

Chris Skinner: I want to widen it out because if the question is financial literacy, it’s not actually in the interest of financial providers for the customers to have financial literacy.

Andrew Vorster: So how can technology improve it? And it doesn’t have to be from a financial service provider. I said how can technology improve financial literacy.

Chris Skinner: I haven’t finished answering the first question yet, because you could take BNPL or payday loans, and they got shut down eventually by regulation in terms of payday loans. BNPL might get that too. There’s nothing wrong with the actual concept. But if you take it out further to loans, credits, and mortgages, overall, that’s how retail banks were making money. And I always remember being on a panel when the 2008 financial crisis hit, and one journalist on the panel said that the retail bankers became very much like drug dealers of credit. You’re pushing the customer further and further over the precipice until they can’t pull back, and that’s how you keep them under your thumb. And that, to me, is still part of the moral compass of banking that we haven’t addressed with regulations, which is if you give customers self-approved mortgages that they then can’t pay back, is that their fault or yours?

Genevieve Leveille: The answer is, that you make it feel like it’s their fault when they go and jump off a cliff. You need more, not just financial literacy, you need more financial oversight of how the drug pushers are making their money.

Andrew Vorster: I’m with you there. Genevieve.

Genevieve Leveille: So your question was how can we use technology for that?

Andrew Vorster: Yes.

Genevieve Leveille: I think that we can take the data, there’s plenty of data out there, to do the education. But we also need to make it a simple language, and sort of, like, explaining the consequences and gamifying it, I think, and that’s the part that… So as was well said, the banks don’t want that to happen. But there is an opportunity to do this. But then the problem is who’s going to make the money? You know, we always say, who’s going to make the money? And there’s no money to be made, only money taken away. So, therefore, you’re going to get killed before you start going at it.

Chris Skinner: But we have things like experience…talking about data, and I find it interesting that, and I made the comment during the last two days, that the people who have the least pay the most for financial services because that’s how you can keep people down. If you’re wealthy, you’re not bothered about credit and lending. If you’re poor, that’s how you live.

Genevieve Leveille: You’re right. But what happens is that let’s just say somebody came out of here and decided to build a technology which is going to…you know, we have the AI, machine learning, all those things to be able to create this, but that company will not survive.

Ritesh Jain: That’s precisely what I said. You’ve got to think from the digital public infrastructure and the digital public goods perspective. You have to think, otherwise, if you leave it to the private companies or the financial institution, it’s not in their interest.

Andrew Vorster: It’s not in their interest.

Ritesh Jain: So if you build the infrastructure, right, and let it run, and enforce the policies around it, and let’s build a public-private partnership, and that’s what the answer is going to be. So yes, technology can enable and help it, but if you think that you are going to build another private organization, which is going to run the financial literacy program across the country, who’s going to fund it?

Chris Skinner: I could see them do that in India, because of a very different structure of thinking and advancement of infrastructure. You wouldn’t see that in the U.K. or America or Europe.

Ritesh Jain: That’s the biggest challenge. Open banking was a great opportunity, right? It still is because it’s in the initial stages. We are eyeing open finance, which we are already seeing in the future. So it’s a great opportunity but we’ve got to think of it more from the infrastructure perspective than how we can enforce the regulations through the infrastructure. And when it comes down to literacy, right, it is not only a financial services challenge, and similarly with inclusion as well. So let’s be realistic. Whether it’s financial inclusion or financial literacy, that’s not only a financial institution’s problem.

Andrew Vorster: It’s a societal one.

Ritesh Jain: That’s a public policy challenge. So policymakers got to act on it.

Genevieve Leveille: So, do you see this as a role that should be taken by companies… organizations such as the World Bank, IMF? I mean, we’ve been giving them money for a long time.

Ritesh Jain: And they have been there for ages, but we haven’t seen enough action. So it got to be the country level.

Jacky Uys: Yes, I agree. I think the World Bank is far removed.

Ritesh Jain: It’s 50,000 level view. It doesn’t work.

Andrew Vorster: I’m going to throw in a little bit of a spanner in the works here because you guys are all saying it’s of no benefit to the financial institution to increase the financial literacy of people. And I’m going to lean on a fellow country person here, and, Jacky, I’m hoping you can jump in and give more of an example here. But in South Africa, Discovery Bank uses psychology and nudges to be able to change people’s behaviors, and they’ve been incredibly successful.

Jacky Uys: Agree. I worked for a competitor, Investec, and we kept our eye very close on Discovery because what Adrian Gore did, and he does it very well, is the psychology part of it. He uses data to drive that insight. He’s very clever because he started with a medical product, and then you’ve got the vitality, so incentivize you to keep the product.

Andrew Vorster: To get physically fitter.

Jacky Uys: Exactly. I’m still wearing this stepper, right? It’s psychologically for me now. Then, he started the insurance business. So he gets more of you…gets more insights of you. Then, while he was doing this, he was busy building his bank. It took him 10 years to build that bank. But now, with the nudging strategy, and I know because I’m a customer of this bank, he nudges you to invest. He’ll say, based on your vitality, status, if you’re on platinum or whatever, why don’t you invest R10,000, and I’m going to meet you at R10,000, this is an example. But that’s what he does with that nudging. I’m financially literate because I’m from a bank. I understand banking. So I put the R10,000 in, and he put the R10,000 in, so I got it. But that’s what he does with that data. The more he knows about the person, the more he builds on his psychology of it.

Andrew Vorster: And it builds their wealth. It doesn’t… So it’s actually of benefit to the bank. They’re not making their money from charging people the overdraft, they’re making their money because their customers are getting financially fitter. And I am very passionate about the fact that technology can help. But at the moment, the models of financial services are stuck. We’ve just spoken about this on the previous panel, legacy thinking, because legacy thinking is forcing them to think the only way that we can make money is from late fees and credit cards and that kind of thing, as opposed to thinking…Discovery Bank completely changed that.

Chris Skinner: So, it’s a coincidence that Adrian was one of the interviews in my brand new book, shameless plug, “Digital For Good.” But I interviewed him because I was looking for good examples of purpose-driven finance. And the whole group started just over…I think it was now 26 years ago, with Adrian saying, “The whole mantra and purpose of our bank is to build wealth through health.” And that’s a very simple statement, but putting that into practice is quite hard.

Now, when you take that further, what you see is all the designs of the products and services that began with insurance, now moving into banking, are all about building wealth through health, and taking that into vitality as over here. But what I realized as I went through the discussions with him, Monzo, and others, was that all of the newer companies, like, a 26-year-old financial group, that still has a strong founder with a strong vision, have those values very clearly in the whole way in which they think about their products and services and the people they hire and how they operate. And I can imagine… Take Barclays Bank Group, for example, when they started in 1697, showing how old they are, it was Quakers.

Andrew Vorster: You were around then, weren’t you?

Genevieve Leveille: He was.

Chris Skinner: Well, I was going to say I remember having that sort of mead with you back in the bar down there. They had those values when they started, I’m sure. Where are they now? And I know the values that Barclays claim to have, but equally, I know that it’s just corporate speak. There’s no passion.

Fintech for a greater good

Jacky Uys: There is a lot of watching going on.

Genevieve Leveille: Do you think though… I think the challenge I would have is what can be done in South Africa or can be done in India is much more agile in a way, and you can take people that way. Well, here, if Barclays were to turn around and start saying, “We’re doing it for the good of the customer,” everybody would look at them, and even the consumer would be like, “What’s wrong with you? What did you drink?” So I think that the idea of being able to learn and bring that in, and maybe this is where the FinTech company, so the young company, should be taking these value set. Right now there is no value set and it’s more about, “This is how I make money. This is how I’m going to make my money. And therefore, I copy what I have seen from before.”

Ritesh Jain: So what I could see in the finance world are we are going back to the values, and we have to regardless. Yes, it’s all about making money, but making money while building a sustainable business, and good for society, good for the people. And there is no other way around it due to sheer competition in the market. So the FinTechs are influencing large financial institutions to flex their muscles and build up at a pace the right products and compete, thanks to open banking as well.

So, what I see is that, yes, we are going to see a bit more sustainable products in the market, whether it’s by choice or by force because the customer is a bit more aware than what they were earlier. When it comes down to financial literacy, again, we need to set out the standard of what we mean by financial literacy. Have a bank account?

Unfortunately, recently, a couple of months back, I was sitting with the state head in one of the states in India. Eighty-nine percent of people have bank accounts or some sort of product, so the financial inclusion is 89%. But when it comes down to financial literacy, there was 24%. The ADB and the UNICEF and the World Bank and everybody was a representative. My only question was, could you please tell me and please explain to me how it works out? You’ve got financial inclusion, 89%, and literacy, 24%, and I bet from this stage, it’s no different in this country as well.

So we need to be clear that what are the standards. And when I asked the question, it was very simple for people to respond that if people have a bank account or a finance product, they’re included. And I said, what about the literacy? So there is no standard. So we need to set out…

Andrew Vorster: We don’t know what it means.

Jacky Uys: But this brings me back to the developed market and the emerging market. I think the emerging markets have no other option but to develop literacy because they’re forever having that image of emerging markets and questions that they have to solve. You know, Europe, and I’ll use Europe as an example, they have the luxury of having money. They have the luxury of the coffers being full. So they’re talking about central bank digital currencies. If I look at central bank digital currencies, the first thing that comes up for me that comes from an emerging market is control over overpopulation, control over spending, and control to make sure the economy’s doing well. It’s for me a very European thing, a very American thing. If you talk about the central bank digital currencies in South Africa, I don’t think it’s a topic that matters because other topics are far greater and more important,

Genevieve Leveille: Sorry, I was going to say but you are having central bank digital currency in the Caribbeans, and that’s taking off because that becomes for them an ability to remove themselves from the control of the U.S. dollar. You should be asking yourself…the distribution and liquidity availability is one of the challenges. So now you start using that ledger sort of a balance. There’s no real cash being moved around and the economy’s just floating.

Jacky Uys: It’s an interesting topic that you’re making. And I also used to have a compliance hat on. For me, that was controversial to see that happen because I’m thinking, what an opportunity to move money through the Caribbean now in the block unanswered. You don’t have to look at anything or anything like that, because it’s in a hidden environment, the movement of the money. So that is quite a controversial one for me. I’m a bit on the fence with that one. It’s more of a micro coffer.

Andrew Vorster: Sorry, Ritesh. You have a response.

Ritesh Jain: I was just referring to, a bit, on a test or different topic related to the banking in the FinTech itself, that yes, we are coming out of the universal banking business model. That’s what we have seen so far, and the banks are risk-averse and everything else, right?

Now, we are seeing that is changing slowly and gradually because of the FinTechs, because of technology, because of customer behavior, adoption, digital, blockchain, AI, ML, you can name it. So we are seeing that change. It will take time. But at the same time, the policymakers have got equal responsibility and more responsibility. When this change is coming in, it got to be right.

Genevieve Leveille: Beep. So can I show after I read what Chris should be talking about, which is the idea, because I read the piece the other day, that in the FinTech world, we’re not working early enough with the regulator? So that’s something that needs to happen. And you need to take that hat, either as Vitality did where I want to…these are the outcomes I want to have, or if I’m going to do a buy now, pay later, that I want to create the mechanism to where the regulator is not going to come in and knock at my door because people who shouldn’t have gotten the loans are there.

Jacky Uys: I’m very interested in what a VC would say to that, because of you…I think if a FinTech has to wait for a regulatory body, I think you remove the speed advantage of the actual industry itself. For me, I agree with the regulation. I think it’s something that you have to follow, with my compliance hat on, but I think there’s a speed advantage as well. But I think there’s a responsibility, and this is where I always look to a founder or a CEO as a human being, saying, “It’s okay that you are doing that product,” but it’s like you’re saying, it’s like, “Are you a drug pusher? Or are you for longevity and financial health? Are you contributing to a healthy society? Or are you contributing to your bottom line?” Because the founders do make a ton of money through the venture capital injections, so they don’t have the potential to make more, if I can put it that way.

Chris Skinner: The point I was making when I was writing about it is that the regulator is allowing and encouraging innovation to happen, which I think they should. But the question is, when do they need to step in and stop the innovation and start to regulate it? And there are many examples. China’s probably the best example of peer-to-peer lending, where over 5,000 companies had launched into the marketplace over 10 years. And finally, after 10 years, the People’s Republic stepped in and said, “Well, to do this, you must have these following rules,” and something like 4,900 peer-to-peer lenders collapsed overnight and everyone lost all their life savings and money. And now, we’ve seen the same in crypto. You know, trillions going into cryptocurrencies, the mega crash of cryptocurrencies, people lost their life savings. The answer is they shouldn’t have put their life savings into cryptocurrencies, but they didn’t have the literacy to know that. And the regulator allows those markets to run. When do they need to step in and stop the innovation?

Now, it was interesting because China very early tried to shut down cryptocurrency exchanges, but in Europe and America, it kind of wasn’t…I won’t say encouraged, but it was encouraged that they were regulated as exchanges. But by regulating them as exchanges, people therefore then thought…

Andrew Vorster: It legitimized them.

Chris Skinner: It legitimized them.

How do attract the right talent in FinTech?

Andrew Vorster: As opposed to China who shut them down then and has now launched a very successful CBDC trial, and that’s probably going to become a model for a lot of the rest of the world. I’m going to… the last thing before we wrap up. We’re nearly getting on there. One of the unanswered questions in FinTech that I see a lot of people struggling with is how the hell they attract the right talent, particularly when the talent that they’re competing for can go work for much sexier places like Google and Facebook and things like that? Who wants to work for a boring bank?

So can technology help attract the right talent in financial services? Or how can technology help attract the right talent in financial services? Or can it? Anybody for that?

Jacky Uys: Not everyone might share my sentiment, but I honestly do believe that the way you structure a deal as you would in a corporate and investment bank, where I’m from, you structure a deal with a human being. You don’t just put salary in front of them, you put shares. It looks like a structure. Structure a package that attracts them.

Andrew Vorster: No technology involved whatsoever?

Jacky Uys: No one retires with pats on the back and that’s the issue. It’s for me. I see that as the main issue.

Ritesh Jain: Precisely what we are seeing across the global market, and it’s a big challenge, the talent scarcity, whether it’s the U.K., European, Asian, anywhere, right? The full stack engineer, we used to say India outsourced quite a lot. The salary of the full stack engineer in India is top-notch. I’m talking about top-notch engineers, it could be as good as London, right? You land up paying quite a lot of money. But to attract the talent you got to structure the deal. But at the same time, from technology, you need to think more from an instant gratification perspective, from a consumer perspective. As a consumer, when we go to buy something, if you get a deal, or 5% off or something on the top, you’re happy.

So you have to think of your employee as a human first, then a resource you will be able to retain. It’s not only about the money. Not everybody… Yes, we got to pay the bills. People work for money, but money is not everything for everybody, right? So you got to build an environment where people can flourish, they can walk themselves into the work, where they can come and discuss openly and share ideas. And that’s the right culture you got to bring in to retain talent. There’s, I don’t think, any other way.

Chris Skinner: I’ve asked this question of quite a few banks, and their answers consistently seem to come back to the same things, which is that most rockstar developers want to feel they’re making a difference and that their work is meaningful and delivers change. And so, if you’re working in the right bank, where they’re leaning in agile and they have all these sorts of flattened organizations that allow small microservices architecture structures of teams working together to act autonomously and not in a, you know, restricted way, then they can see the change they make to code on a Friday has been used by their mom and dad or friends on a Monday, and they go, “All right. That’s making a difference.”

Developers can start to feel that their work is meaningful. And more than that, and JPMorgan Chase made this comment, is that if you were working for Google or Facebook, you’d be in Silicon Valley. That’s going to cost you a fortune in housing and other costs, whereas we’ll allow you to work anywhere across America. But if you want to work in Silicon Valley, we’ve got a campus there between Google and Facebook where you can be in that environment, because they’ve opened a large developers’ campus, which is experimental, so you can work on experimental new technologies and other ideas. And then, a comment that was made to me quite recently in the current meltdown in FinTech, and particularly in BNPL, for example, is that if you’ve got hundreds of people being laid off by the Klarnas of this world, who do you think is going to pick them up? The big banks.

Andrew Vorster: Genevieve , any last words on that one? Because we’re going to wrap up the panel on that.

Genevieve Leveille: I would just say the key is purpose. So it’s really how to bring in the three P’s, people, planet, and purpose. And that’s really where we’re seeing it. And I think when we start looking at Gen Z, this is what’s important. And in reality, that’s who we’re probably building for.

Andrew Vorster: All right. And on that note, please give my panel a round of applause. Thank you very much for your comments and insights. And with that, I think that we’ve got pizza and beverages, alcoholic and non-alcoholic, downstairs. Am I correct? I’m looking around for the organizers to signal yes. All good. Yes. And please carry on with the conversation with these people up here downstairs in a social environment. Thank you for your time tonight. Cheers.

The post How Can Technology Answer the Questions Still Unanswered in FinTech? appeared first on Erlang Solutions.

by Erlang Admin at August 22, 2022 10:30

Prosodical Thoughts

Starring roles: Introducing dynamic permissions in Prosody

We just pushed the first stage of our modern auth project to Prosody’s development branch!

In previous versions of Prosody (0.12 and earlier), Prosody’s internal API only really supported one type of permission check: “is this user an admin?”. Our new work replaces this with a fully flexible roles/permissions system.

Upgrading to the new system

Despite all our excitement about this new feature, the new changes are designed to be largely invisible to server admins by default. We always aim to make Prosody upgrades as smooth as possible, and we have ensured that no configuration changes are necessary.

If you previously used Prosody’s earlier experimental support for roles in 0.12.x (very unlikely) and assigned roles to users, there is a data migration command to run: prosodyctl mod_authz_internal migrate. This feature in 0.12 was undocumented and therefore unused by most deployments.

There are, however, some changes for module developers to be aware of. This may affect some community modules, though we’ve already updated the major ones ourselves. If you have developed your own custom modules, you may also need to update those. Details about the API changes are discussed later in this post. If you encounter any issues, please do report them to the relevant places.

Keeping it simple

One of our project’s primary goals has always been to keep things as light and simple as possible. Access control is an amazingly complex topic once you scratch the surface, and it’s easy to drown in a sea of roles, permissions and policies.

To keep complexity down, we made some decisions early on about what not to support, so we could instead focus on a minimalist core API and interface that can still support a range of use-cases.

For example, while some systems allow a user to have multiple roles assigned, we decided that any given session should only have one active role at a time. As well as simplifying code, this decision also makes things easier for a human to reason about (e.g. you don’t have to wonder what happens if role A forbids an action and role B permits it, and both are assigned to the same user!).

To keep some flexibility, we do allow multiple “secondary” roles to be assigned to a user. This list simply provides a list of alternative roles the user is permitted to use when requested.

Viewing and managing roles

Currently the best way to view and manage roles is via the admin console. We have added roles to the default output of c2s:show(), and new commands to show and modify the primary role of users.

prosody@prosody: ~/ $ prosodyctl shell c2s show 
Session ID           | JID                              | Role           |
c2s5618e2f92150      | admin@localhost/gajim.M1S9AUK2   | prosody:admin  |
c2s5618e38167e0      | test1@localhost/gajim.FQJLBQIN   | prosody:user   |
OK: 2 c2s sessions shown

Custom roles and permissions

A big reason for the new permissions framework is so that server admins can have more control over permissions. To achieve this, we’ve made it possible to define custom roles and permission policies directly in the config file.

For example, previously mod_announce would let you send an announcement to all users on the server only if you were a server admin. But what if you want to grant this permission to a bot or a script, without giving that bot full admin access to everything else on the server?

Simple! Create a new role for your announcement bot, let’s call it for example “announcer”. Then we just need to give it the “mod_announce:send-announcement” permission. The config looks like this:

VirtualHost ""

  custom_roles = {
          name = "announcer";
          inherits = { "prosody:user" };
          allow = {

This creates a new role that has all the same permissions as a normal user, but with the extra permission to send announcements. After assigning this role to your bot’s user account, it will have permission to send announcements but won’t be able to access any of the other features usually reserved for admins.

Changes for module developers

Deprecation of is_admin API

The old permissions API (usermanager.is_admin()) has been deprecated. Usually we take a more gradual approach to deprecating APIs that are used by modules, however we have special reasons for removing this one.

The deprecated API accepts only a JID (which can be a local or remote user), and returns true or false depending on whether they have admin privileges on the specified host.

The problem is that our new system allows per-session roles. It’s possible for an admin to connect with a client that they don’t want to have full admin access to the server. In this case the session would have a more restrictive role assigned.

However, any modules that continue to use the is_admin() API can only perform permission checks on the JID, and they cannot make any decisions about a specific session. This could lead to a bypass of access control.

To ease the transition, we have initially kept is_admin() working. It will continue to return true if the JID’s default role is prosody:admin or prosody:operator, though it will emit a warning and traceback in the logs for easy identification.

In the near future, it will be disabled - that is, it will log an error and always return false (even if the JID has an admin/operator role).

For admins who want to enforce the new behaviour early, or keep the current (warning only) behaviour for a bit longer, you can set the global option strict_deprecate_is_admin to true or false (it currently defaults to false, and will default to true in a future nightly build at least a week from the date of this post). This is a temporary solution though: eventually this option and the compatibility mechanism will be removed.

Switching to the new API

To ensure your module continues to work with Prosody’s development branch and future Prosody versions, you need to replace all usage of the is_admin() API. If you don’t use this API, great, there is nothing you need to do!

If you do use is_admin(), you should switch to the new role API. This is not provided by Prosody 0.12 and earlier, but to keep compatibility with those versions you can use our new module, mod_compat_roles. Simply add to the top of your module this line:


This will make available the new module API methods (module:may(), module:default_permission()). Note that it won’t provide many other features such as the new role management API in usermanager, or the ability for admins to define custom roles and permissions.

If you have code that looks like:

if usermanager.is_admin(sender_jid, then
  -- Perform some action

Decide on a name for the action that is being performed, and then change it to something like:

if module:may(":my-action", event) then
  -- Perform some action

By default nobody will have permission to perform your new action, so you will also want to add near the top of your module a default policy for this action:

-- Allow admins to perform this action by default
module:default_permission("prosody:admin", ":my-action");

You can find the full API documentation here.

Coming next

While this new feature is just a part of the current modern auth project, we’re very excited about the new possibilities it already brings to Prosody - improvements that can be used right now.

However, we’re also looking forward to the next stages. With the authorization layer now in place, acting as the foundations, we’ll be moving on to the second stage: authentication. This will allow clients to authenticate with the server using XEP-0388 (Extensible SASL Profile) with support for advanced features such as multi-factor authentication.

Stay tuned for further updates about this project in the near future!

by The Prosody Team at August 22, 2022 09:15