Repository: deltachat/deltachat-core-rust (language: python)

Issue:
change add-to-group/secure-join QR code data from `OPENPGP4FPR:`- to `i.delta.chat`-scheme
using `https://i.delta.chat...` links in the QR codes allows users to scan the QR code with any mobile _without having delta chat installed yet._

users will then get instructions how to install delta chat, resulting in a much better ux workflow as sharing such a link works in more cases.

to be clear: scanning from Delta Chat still does not do any calls to `i.delta.chat` or to somewhere else -  `i.delta.chat` can even be down or being blocked.

drawback would only be that openkeychain won't be able to scan these codes, however, not sure if someone ever did that (the other way round, will still work - and openkeychain can be fixed as well)

question is about timing:

starting with 1.44 releases (using core 1.134.0 and merged #5219), `i.delta.chat` links in QR codes are accepted equivalent to `OPENPGP4FPR:` (in fact, they differ only by first `&`/`#`)

so, if we change the QR codes in the upcoming 1.46, an 1.42 does not support these QR codes directly - but maybe that's okay as Delta Chat offers to open the URL in the browser - and from there, one should be able to do the join. so, maybe  the benefits of getting new users are more important than to support ppl that did not upgrade :)  
but the new flow should definetely be tested with a 1.42

---

EDIT: what should also be tested before targeting this issue,  is what happens when "common" system cameras scan the i.delta.chat code when delta chat is installed. if delta chat is opened for `OPENPGP4FPR:` directly, it would be cool if that happens also for `i.delta.chat`.

**here is are two test QR codes that should ideally behave the same** when scanning with the **system camera** (no need to check from inside delta chat)

<img width=300 src=https://github.com/deltachat/deltachat-core-rust/assets/9800740/46ee9fa7-a8c9-412b-84b5-e848eaa1f6d0> &nbsp; &nbsp; <img width=300  src=https://github.com/deltachat/deltachat-core-rust/assets/9800740/f32292d0-a2e0-4608-81fd-a4f44195b8f0>

(just check if the message "Chat with Bob...?" is asked, no need to really do the join, Bob is probably offline anyways :)

the qr codes contain the data `https://i.delta.chat/#4BBB21F24BF172148246CFAA5FB0363572FC9FE1&a=siznq0vgz%40nine.testrun.org&n=bob&i=Sh3Dwasz8K5&s=UjY23SgefLv`resp. `OPENPGP4FPR:4BBB21F24BF172148246CFAA5FB0363572FC9FE1#a=siznq0vgz%40nine.testrun.org&n=bob&i=Sh3Dwasz8K5&s=UjY23SgefLv`
- ✅ iOS 17 system camera opens Delta  Chat for both codes
- ✅ iOS 15 system camera opens Delta  Chat for both codes
- ✅ LG CAM system camera  opens none of the codes on android7 (failing for both is no worsening, so: check)
- ✅ F-Droid's "Barcode Scanner" allows to open Delta Chat for both codes
- ✅ ASUS / Android 10 system camera allows to open Delta Chat for both codes
- ❓ <your test here - or comment below>

what's expected on android is a dialog asking for the app that should be used to open the link (the dialog appears only when delta chat was not set as default before)
change add-to-group/secure-join QR code data from `OPENPGP4FPR:`- to `i.delta.chat`-scheme
using `https://i.delta.chat...` links in the QR codes allows users to scan the QR code with any mobile _without having delta chat installed yet._

users will then get instructions how to install delta chat, resulting in a much better ux workflow as sharing such a link works in more cases.

to be clear: scanning from Delta Chat still does not do any calls to `i.delta.chat` or to somewhere else -  `i.delta.chat` can even be down or being blocked.

drawback would only be that openkeychain won't be able to scan these codes, however, not sure if someone ever did that (the other way round, will still work - and openkeychain can be fixed as well)

question is about timing:

starting with 1.44 releases (using core 1.134.0 and merged #5219), `i.delta.chat` links in QR codes are accepted equivalent to `OPENPGP4FPR:` (in fact, they differ only by first `&`/`#`)

so, if we change the QR codes in the upcoming 1.46, an 1.42 does not support these QR codes directly - but maybe that's okay as Delta Chat offers to open the URL in the browser - and from there, one should be able to do the join. so, maybe  the benefits of getting new users are more important than to support ppl that did not upgrade :)  
but the new flow should definetely be tested with a 1.42

---

EDIT: what should also be tested before targeting this issue,  is what happens when "common" system cameras scan the i.delta.chat code when delta chat is installed. if delta chat is opened for `OPENPGP4FPR:` directly, it would be cool if that happens also for `i.delta.chat`.

**here is are two test QR codes that should ideally behave the same** when scanning with the **system camera** (no need to check from inside delta chat)

<img width=300 src=https://github.com/deltachat/deltachat-core-rust/assets/9800740/46ee9fa7-a8c9-412b-84b5-e848eaa1f6d0> &nbsp; &nbsp; <img width=300  src=https://github.com/deltachat/deltachat-core-rust/assets/9800740/f32292d0-a2e0-4608-81fd-a4f44195b8f0>

(just check if the message "Chat with Bob...?" is asked, no need to really do the join, Bob is probably offline anyways :)

the qr codes contain the data `https://i.delta.chat/#4BBB21F24BF172148246CFAA5FB0363572FC9FE1&a=siznq0vgz%40nine.testrun.org&n=bob&i=Sh3Dwasz8K5&s=UjY23SgefLv`resp. `OPENPGP4FPR:4BBB21F24BF172148246CFAA5FB0363572FC9FE1#a=siznq0vgz%40nine.testrun.org&n=bob&i=Sh3Dwasz8K5&s=UjY23SgefLv`
- ✅ iOS 17 system camera opens Delta  Chat for both codes
- ✅ iOS 15 system camera opens Delta  Chat for both codes
- ✅ LG CAM system camera  opens none of the codes on android7 (failing for both is no worsening, so: check)
- ✅ F-Droid's "Barcode Scanner" allows to open Delta Chat for both codes
- ✅ ASUS / Android 10 system camera allows to open Delta Chat for both codes
- ❓ <your test here - or comment below>

what's expected on android is a dialog asking for the app that should be used to open the link (the dialog appears only when delta chat was not set as default before)


Discussion / hints:
We have already changed the code for contact verification on various devices (like desktop: https://github.com/deltachat/deltachat-desktop/pull/3650), so this would only affect **group** invite codes.

Also would be great we would let core do the the conversion between the links on all UIs: https://github.com/deltachat/invite/issues/28
> We have already changed the code for contact verification on various devices (like desktop: https://github.com/deltachat/deltachat-desktop/pull/3650), so this would only affect group invite codes.

i do not think, this is true. imu, this, and comparable changes, affects the code copied-to-clipboard only or what is shared on android/ios - but then not only for groups but also for secure-join-links.

the suggested change of the issue is about changing the _QR code data_ that is shown in Delta Chat

what's true is that the hacks about copying slightly different data to clipboard or share them, can be removed as the core just always deals with i.delta.chat links (and support openpgp4fpr for legacy reasons)
> the suggested change of the issue is about changing the QR code data that is shown in Delta Chat

good to know that the qr code data was not changed yet. anyways makes sense to not only change the svg, but also the returned qr code data in core and remove the conversion logic from the UI. (so core directly returns the invite links instead of  OPENPGP4FPR).

in technical words:
- make both `get_securejoin_qr` and `get_securejoin_qr_svg` both return invite links
- detection in core (`dc_check_qr`) already supports invite links and OPENPGP4FPR
- so then we can remove all conversion logic from the UI's (some code areas are linked in https://github.com/deltachat/invite/issues/28)
> anyways makes sense to not only change the svg, but also the returned qr code data in core and remove the conversion logic from the UI.

this is how the change is meant to be. [`dc_get_securejoin_qr_svg()`](https://c.delta.chat/classdc__context__t.html#ab32aaf3b05974b0944156c98eed6e711) probably calls [`dc_get_securejoin_qr()`](https://c.delta.chat/classdc__context__t.html#a586a3211762fd27924f53c316955e03d), so only the latter needs to be adapted
why do we need the QR data to be a i.delta.chat link???
I think it is better if the QR data is just the needed data to avoid longer QR data (harder to decode QR) or incompatibility with other `OPENPGP4FPR:`-supporting apps, including old DC clients

for generating the link instead of client-side, a new api "get_invitelink()` could be added :thinking: 
> why do we need the QR data to be a i.delta.chat link???

to allow it being scanned unconditionally, with or without delta chat being installed.

- if you scan it without delta chat installed, you get on the invite link, telling you what to do, where to download etc.

- if you scan it with delta chat installed, nothing changes (nothing is done with i.delta.chat, the server can be offline even)

for the length: it adds 9 characters, that seems a cheap price for the added functionality. for compatibility, see discussion in the initial post
> to allow it being scanned unconditionally, with or without delta chat being installed.

I just re-read the original post and realized I missed that bit, yes good point I think it is worthy :+1: 
Using an up-to-date Google Pixel 8 (Android 14, stock ROM and camera, Firefox browser):

The scan of the first QR code offers to open the link to `i.delta.chat` in the web browser:
![grafik](https://github.com/deltachat/deltachat-core-rust/assets/51095533/06926169-f34f-4753-a2b6-a42d2c4dd1ab)

The scan of the second QR code offers to open a `OPENPGP4FPR` link in an app that is registered to be able to open `OPENPGP4FPR` links. If there is more than one app installed for that purpose, the user can choose the appropriate one. Choosing Delta Chat leads to this window in it:
![grafik](https://github.com/deltachat/deltachat-core-rust/assets/51095533/5a76f322-92b6-46d3-9b50-0f08b110ff78)
also for me it made it worse in a Xiaomi device:

the first QR offers to copy text/link to clipboard (not even to open browser!?)

second link offers to open delta chat


on CalyxOS device:

first link offers to open the browser (even if DC is installed, for some reason is not verified that the app can handle the i.delta.chat links)

while the second link offers to copy text to clipboard, not to open directly in delta chat either :(
> also for me it made it worse in a Xiaomi device:
> 
> the first QR offers to copy text/link to clipboard (not even to open browser!?)
> 
> second link offers to open delta chat

same behavior on Redmi 9A (which is Xiaomi I think)
so, all in all it seems a bit questionable, and seems to worsen things on some devices.

it maybe still makes sense to do the change, however, to free up thinking resources, it's no longer needed to be closed for  1.46
`OPENPGP4FPR:` is not clickable in most places, like other messengers, because they only linkify the most common schemes.
On the other hand you could say that the openpgp fingerprint might take longer to block for sites like Facebook because it is not a common link/website... anyways I think at least for copy to clipboard we should use the website invite links.
Worst case we could have a method parameter that lets us switch between the two formats? so UI could decide.
> question is about timing:
> 
> starting with 1.44 releases [...] i.delta.chat links in QR codes are accepted equivalent to OPENPGP4FPR: 

also also discussed offline, we should do the change.

compared to the huge advantages that the QR codes start working without Delta Chat being installed, the drawbacks are negligible (only notable drawback is that _in rare cases_ qr codes scanned with the system camera may not open in Delta Chat directly - but even in these cases, you can open Delta Chat and the invite-link from the browser)

however, as this is a pretty sensible area, we should create/adapt tests and also test that in practise carefully :)
We have already changed the code for contact verification on various devices (like desktop: https://github.com/deltachat/deltachat-desktop/pull/3650), so this would only affect **group** invite codes.

Also would be great we would let core do the the conversion between the links on all UIs: https://github.com/deltachat/invite/issues/28
> We have already changed the code for contact verification on various devices (like desktop: https://github.com/deltachat/deltachat-desktop/pull/3650), so this would only affect group invite codes.

i do not think, this is true. imu, this, and comparable changes, affects the code copied-to-clipboard only or what is shared on android/ios - but then not only for groups but also for secure-join-links.

the suggested change of the issue is about changing the _QR code data_ that is shown in Delta Chat

what's true is that the hacks about copying slightly different data to clipboard or share them, can be removed as the core just always deals with i.delta.chat links (and support openpgp4fpr for legacy reasons)
> the suggested change of the issue is about changing the QR code data that is shown in Delta Chat

good to know that the qr code data was not changed yet. anyways makes sense to not only change the svg, but also the returned qr code data in core and remove the conversion logic from the UI. (so core directly returns the invite links instead of  OPENPGP4FPR).

in technical words:
- make both `get_securejoin_qr` and `get_securejoin_qr_svg` both return invite links
- detection in core (`dc_check_qr`) already supports invite links and OPENPGP4FPR
- so then we can remove all conversion logic from the UI's (some code areas are linked in https://github.com/deltachat/invite/issues/28)
> anyways makes sense to not only change the svg, but also the returned qr code data in core and remove the conversion logic from the UI.

this is how the change is meant to be. [`dc_get_securejoin_qr_svg()`](https://c.delta.chat/classdc__context__t.html#ab32aaf3b05974b0944156c98eed6e711) probably calls [`dc_get_securejoin_qr()`](https://c.delta.chat/classdc__context__t.html#a586a3211762fd27924f53c316955e03d), so only the latter needs to be adapted
why do we need the QR data to be a i.delta.chat link???
I think it is better if the QR data is just the needed data to avoid longer QR data (harder to decode QR) or incompatibility with other `OPENPGP4FPR:`-supporting apps, including old DC clients

for generating the link instead of client-side, a new api "get_invitelink()` could be added :thinking: 
> why do we need the QR data to be a i.delta.chat link???

to allow it being scanned unconditionally, with or without delta chat being installed.

- if you scan it without delta chat installed, you get on the invite link, telling you what to do, where to download etc.

- if you scan it with delta chat installed, nothing changes (nothing is done with i.delta.chat, the server can be offline even)

for the length: it adds 9 characters, that seems a cheap price for the added functionality. for compatibility, see discussion in the initial post
> to allow it being scanned unconditionally, with or without delta chat being installed.

I just re-read the original post and realized I missed that bit, yes good point I think it is worthy :+1: 
Using an up-to-date Google Pixel 8 (Android 14, stock ROM and camera, Firefox browser):

The scan of the first QR code offers to open the link to `i.delta.chat` in the web browser:
![grafik](https://github.com/deltachat/deltachat-core-rust/assets/51095533/06926169-f34f-4753-a2b6-a42d2c4dd1ab)

The scan of the second QR code offers to open a `OPENPGP4FPR` link in an app that is registered to be able to open `OPENPGP4FPR` links. If there is more than one app installed for that purpose, the user can choose the appropriate one. Choosing Delta Chat leads to this window in it:
![grafik](https://github.com/deltachat/deltachat-core-rust/assets/51095533/5a76f322-92b6-46d3-9b50-0f08b110ff78)
also for me it made it worse in a Xiaomi device:

the first QR offers to copy text/link to clipboard (not even to open browser!?)

second link offers to open delta chat


on CalyxOS device:

first link offers to open the browser (even if DC is installed, for some reason is not verified that the app can handle the i.delta.chat links)

while the second link offers to copy text to clipboard, not to open directly in delta chat either :(
> also for me it made it worse in a Xiaomi device:
> 
> the first QR offers to copy text/link to clipboard (not even to open browser!?)
> 
> second link offers to open delta chat

same behavior on Redmi 9A (which is Xiaomi I think)
so, all in all it seems a bit questionable, and seems to worsen things on some devices.

it maybe still makes sense to do the change, however, to free up thinking resources, it's no longer needed to be closed for  1.46
`OPENPGP4FPR:` is not clickable in most places, like other messengers, because they only linkify the most common schemes.
On the other hand you could say that the openpgp fingerprint might take longer to block for sites like Facebook because it is not a common link/website... anyways I think at least for copy to clipboard we should use the website invite links.
Worst case we could have a method parameter that lets us switch between the two formats? so UI could decide.
> question is about timing:
> 
> starting with 1.44 releases [...] i.delta.chat links in QR codes are accepted equivalent to OPENPGP4FPR: 

also also discussed offline, we should do the change.

compared to the huge advantages that the QR codes start working without Delta Chat being installed, the drawbacks are negligible (only notable drawback is that _in rare cases_ qr codes scanned with the system camera may not open in Delta Chat directly - but even in these cases, you can open Delta Chat and the invite-link from the browser)

however, as this is a pretty sensible area, we should create/adapt tests and also test that in practise carefully :)

Fix patch:
diff --git a/src/securejoin.rs b/src/securejoin.rs
index 7118c8db28..b66277597c 100644
--- a/src/securejoin.rs
+++ b/src/securejoin.rs
@@ -104,7 +104,7 @@ pub async fn get_securejoin_qr(context: &Context, group: Option<ChatId>) -> Resu
             context.scheduler.interrupt_inbox().await;
         }
         format!(
-            "OPENPGP4FPR:{}#a={}&g={}&x={}&i={}&s={}",
+            "https://i.delta.chat/#{}&a={}&g={}&x={}&i={}&s={}",
             fingerprint.hex(),
             self_addr_urlencoded,
             &group_name_urlencoded,
@@ -119,7 +119,7 @@ pub async fn get_securejoin_qr(context: &Context, group: Option<ChatId>) -> Resu
             context.scheduler.interrupt_inbox().await;
         }
         format!(
-            "OPENPGP4FPR:{}#a={}&n={}&i={}&s={}",
+            "https://i.delta.chat/#{}&a={}&n={}&i={}&s={}",
             fingerprint.hex(),
             self_addr_urlencoded,
             self_name_urlencoded,


Test patch:
diff --git a/python/tests/test_3_offline.py b/python/tests/test_3_offline.py
index f6eb248c14..dcd752d551 100644
--- a/python/tests/test_3_offline.py
+++ b/python/tests/test_3_offline.py
@@ -705,7 +705,7 @@ def test_qr_setup_contact(self, acfactory):
         ac1 = acfactory.get_pseudo_configured_account()
         ac2 = acfactory.get_pseudo_configured_account()
         qr = ac1.get_setup_contact_qr()
-        assert qr.startswith("OPENPGP4FPR:")
+        assert qr.startswith("https://i.delta.chat")
         res = ac2.check_qr(qr)
         assert res.is_ask_verifycontact()
         assert not res.is_ask_verifygroup()