Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b83d897
smp protocol: short links and other changes from RFC (#1489)
epoberezkin Mar 26, 2025
1dd677e
Merge branch 'master' into short-links
epoberezkin Mar 28, 2025
c1a6647
agent: join connection when 1-time invitation short link is already s…
epoberezkin Mar 29, 2025
04cbed9
agent: set/update and delete contact short link data (#1499)
epoberezkin Mar 30, 2025
56bec06
smp protocol: remove creating notifications from NEW command, new ide…
epoberezkin Mar 30, 2025
dd67de4
Merge branch 'master' into short-links
epoberezkin Mar 31, 2025
94ee3ce
agent: replace sndSecure with queueMode in queue URIs and records (#1…
epoberezkin Mar 31, 2025
2c5530c
agent: binary protocol encoding for connection request (#1503)
epoberezkin Apr 1, 2025
7ec0ae3
agent: types and encodings to use from the app (#1504)
epoberezkin Apr 3, 2025
a2a4b80
agent: padded encryption for link data, shorten/restore short links, …
epoberezkin Apr 5, 2025
3a3f9fd
Merge branch 'master' into short-links
epoberezkin Apr 10, 2025
b7a9542
smp server: short links and owners for channels (#1506)
epoberezkin Apr 10, 2025
bdf8bf0
smp server: make symlinks relative
epoberezkin Apr 10, 2025
a66163d
agent: additional short link types and encodings (#1509)
epoberezkin Apr 11, 2025
37ce109
smp server: .well-known folder for server pages for SimpleX apps to h…
epoberezkin Apr 11, 2025
76aad61
smp server: update server page for short links to correctly change UR…
epoberezkin Apr 11, 2025
307a784
Merge branch 'master' into short-links
epoberezkin Apr 13, 2025
ccdd8e1
agent: additional encodings for short links
epoberezkin Apr 13, 2025
c2c4730
smp server: serve .well-known folder via server pages (#1514)
epoberezkin Apr 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,23 @@ jobs:
uses: actions/checkout@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: simplex-chat/docker-setup-buildx-action@v3

- name: Install PostgreSQL 15 client tools
if: matrix.os == '22.04'
shell: bash
run: |
# Import the repository signing key
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
# Add the PostgreSQL APT repository
sudo sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
# Update repository and install postgresql tools
sudo apt update
sudo apt -y install postgresql-client-15

- name: Build and cache Docker image
uses: docker/build-push-action@v6
uses: simplex-chat/docker-build-push-action@v6
with:
context: .
load: true
Expand Down Expand Up @@ -82,7 +95,7 @@ jobs:
build/${{ matrix.platform_name }}:latest

- name: Build smp-server (postgresql) and tests
shell: docker exec -t builder sh {0}
shell: docker exec -t builder sh -eu {0}
run: |
cabal update
cabal build --jobs=$(nproc) --enable-tests -fserver_postgres
Expand All @@ -106,7 +119,7 @@ jobs:
docker cp builder:/out/smp-server ./smp-server-postgres-ubuntu-${{ matrix.platform_name }}

- name: Build everything else (standard)
shell: docker exec -t builder sh {0}
shell: docker exec -t builder sh -eu {0}
run: |
cabal build --jobs=$(nproc)
mkdir -p /out
Expand All @@ -127,7 +140,7 @@ jobs:
- name: Build changelog
if: startsWith(github.ref, 'refs/tags/v')
id: build_changelog
uses: mikepenz/release-changelog-builder-action@v5
uses: simplex-chat/release-changelog-builder-action@v5
with:
configuration: .github/changelog_conf.json
failOnError: true
Expand All @@ -138,7 +151,7 @@ jobs:

- name: Create release
if: startsWith(github.ref, 'refs/tags/v') && matrix.ghc != '8.10.7'
uses: softprops/action-gh-release@v2
uses: simplex-chat/action-gh-release@v2
with:
body: |
See full changelog [here](https://github.com/simplex-chat/simplexmq/blob/master/CHANGELOG.md).
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ jobs:
uses: actions/checkout@v4

- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: simplex-chat/docker-login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Extract metadata for Docker image
id: meta
uses: docker/metadata-action@v5
uses: simplex-chat/docker-metadata-action@v5
with:
images: ${{ secrets.DOCKERHUB_USERNAME }}/${{ matrix.app }}
flavor: |
Expand All @@ -40,7 +40,7 @@ jobs:
type=semver,pattern=v{{major}}

- name: Build and push Docker image
uses: docker/build-push-action@v6
uses: simplex-chat/docker-build-push-action@v6
with:
push: true
build-args: |
Expand Down
49 changes: 49 additions & 0 deletions apps/smp-server/static/.well-known/apple-app-site-association
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"applinks": {
"details": [
{
"appIDs": [
"5NN7GUYB6T.chat.simplex.app"
],
"components": [
{
"/": "/contact/*"
},
{
"/": "/contact"
},
{
"/": "/invitation/*"
},
{
"/": "/invitation"
},
{
"/": "/a/*"
},
{
"/": "/a"
},
{
"/": "/c/*"
},
{
"/": "/c"
},
{
"/": "/g/*"
},
{
"/": "/g"
},
{
"/": "/i/*"
},
{
"/": "/i"
}
]
}
]
}
}
16 changes: 16 additions & 0 deletions apps/smp-server/static/.well-known/assetlinks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "chat.simplex.app",
"sha256_cert_fingerprints": [
"5E:3E:DC:C2:00:FB:A8:D5:F4:88:F3:CA:4C:32:5B:05:78:C5:6A:9C:03:A1:CC:B5:92:9C:D7:5C:7E:57:E2:4D",
"3C:52:C4:FD:3C:AD:1C:07:C9:B0:0A:70:80:E3:58:FA:B9:FE:FC:B8:AF:5A:EC:14:77:65:F1:6D:0F:21:AD:85",
"AE:C1:95:DC:FD:46:14:BD:3A:91:EC:26:D1:D5:14:C8:75:71:C5:CC:8D:CF:48:08:3F:92:83:14:3C:A2:B9:A6"
]
}
}
]
1 change: 1 addition & 0 deletions apps/smp-server/static/a/index.html
1 change: 1 addition & 0 deletions apps/smp-server/static/c/index.html
1 change: 1 addition & 0 deletions apps/smp-server/static/i/index.html
25 changes: 12 additions & 13 deletions apps/smp-server/static/link.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@
class="hidden xl:block h-screen pt-[66px] bg-white dark:bg-gradient-radial-mobile dark:lg:bg-gradient-radial">
<div class="container m-auto h-full flex items-center justify-between px-5">
<div class="flex flex-col items-start justify-center w-full">
<h1 class="text-[38px] leading-[43px] font-bold max-w-[500px] mb-[30px] primary-header-contact">You received a
1-time link to connect on SimpleX Chat</h1>
<h1 class="text-[38px] leading-[43px] font-bold max-w-[500px] mb-[30px] primary-header-contact">This is a one-time link of the SimpleX&nbsp;network user</h1>
<h2
class="text-[20px] leading-[28px] text-[#606C71] dark:text-white font-bold max-w-[475px] mb-[80px] secondary-header-contact">
Scan the QR code with the SimpleX Chat app on your phone or tablet.</h2>
Expand Down Expand Up @@ -184,10 +183,8 @@ <h1 class="text-[38px] leading-[43px] font-bold max-w-[500px] mb-[30px] primary-
class="block xl:hidden pt-[106px] py-[90px] bg-white dark:bg-gradient-radial-mobile dark:lg:bg-gradient-radial">
<div class="container m-auto px-5">
<div class="flex flex-col items-center">
<h1 class="text-[28px] font-bold text-center max-w-[602px] mb-[40px] primary-header-contact">You received a
1-time link to connect on SimpleX Chat</h1>
<p class="text-[20px] leading-[28px] text-grey-black dark:text-white font-medium mb-[30px]">To make a
connection:</p>
<h1 class="text-[28px] font-bold text-center max-w-[602px] mb-[40px] primary-header-contact">This is a one-time link of the SimpleX&nbsp;network user</h1>
<p class="text-[20px] leading-[28px] text-grey-black dark:text-white font-medium mb-[30px]">To make a connection:</p>
<div
class="flex flex-col justify-center items-center p-4 w-full max-w-[468px] min-h-[131px] rounded-[30px] border-[1px] border-[#A8B0B4] dark:border-white border-opacity-60 mb-6 relative">
<p class="text-xl font-medium text-grey-black dark:text-white mb-4">Install SimpleX app</p>
Expand Down Expand Up @@ -506,13 +503,15 @@ <h2 class="text-xl font-bold">If you already installed SimpleX Chat for the term
const url = window.location.href
const messageElements = document.getElementsByClassName('primary-header-contact')

if (url.includes('/invitation')) {
for (let element of messageElements) {
element.textContent = 'You received a 1-time link to connect on SimpleX Chat'
}
} else {
for (let element of messageElements) {
element.textContent = 'You received an address to connect on SimpleX Chat'
for (let element of messageElements) {
if (url.includes('/g') || url.includes('&data=%7B%22groupLinkId%22%3A')) {
element.innerHTML = 'This is a public group address on SimpleX&nbsp;network'
} else if (url.includes('/a') || url.includes('/contact')) {
element.innerHTML = 'This is a public address of the SimpleX&nbsp;network user'
} else if (url.includes('/i') || url.includes('/invitation')) {
element.innerHTML = 'This is a one-time link of the SimpleX&nbsp;network user'
} else if (url.includes('/c')) {
element.innerHTML = 'This is a public channel address on SimpleX&nbsp;network'
}
}
</script>
Expand Down
13 changes: 12 additions & 1 deletion apps/smp-server/static/media/contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,18 @@
parsedURI.pathname = "/" + action
connURI = parsedURI.toString()
console.log("connection URI: ", connURI)
mobileConnURIanchor.href = "simplex:" + parsedURI.pathname + parsedURI.hash
const hash = parsedURI.hash
const hostname = parsedURI.hostname
let appURI = "simplex:" + parsedURI.pathname
appURI += action.length > 1 // not short link
? hash
: !hash.includes("?") // otherwise add server hostname
? hash + "?h=" + hostname // no parameters
: !hash.includes("?h=") && !hash.includes("&h=")
? hash + "&h=" + hostname // no "h" parameter
: hash.replace(/([?&])h=([^&]+)/, `$1h=${hostname},$2`) // add as the first hostname to "h" parameter
mobileConnURIanchor.href = appURI
console.log("app URI: ", appURI)
connURIel.innerText = "/c " + connURI
for (const connQRCode of connQRCodes) {
try {
Expand Down
47 changes: 35 additions & 12 deletions apps/smp-server/web/Static.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import Data.Maybe (fromMaybe)
import Data.String (fromString)
import Data.Text.Encoding (encodeUtf8)
import Network.Socket (getPeerName)
import Network.Wai (Application)
import Network.Wai (Application, Request (..))
import Network.Wai.Application.Static (StaticSettings (..))
import qualified Network.Wai.Application.Static as S
import qualified Network.Wai.Handler.Warp as W
import qualified Network.Wai.Handler.Warp.Internal as WI
Expand All @@ -31,12 +32,13 @@ import System.Directory (createDirectoryIfMissing)
import System.FilePath
import UnliftIO.Concurrent (forkFinally)
import UnliftIO.Exception (bracket, finally)
import qualified WaiAppStatic.Types as WAT

serveStaticFiles :: EmbeddedWebParams -> IO ()
serveStaticFiles EmbeddedWebParams {webStaticPath, webHttpPort, webHttpsParams} = do
forM_ webHttpPort $ \port -> flip forkFinally (\e -> logError $ "HTTP server crashed: " <> tshow e) $ do
logInfo $ "Serving static site on port " <> tshow port
W.runSettings (mkSettings port) (S.staticApp $ S.defaultFileServerSettings webStaticPath)
W.runSettings (mkSettings port) app
forM_ webHttpsParams $ \WebHttpsParams {port, cert, key} -> flip forkFinally (\e -> logError $ "HTTPS server crashed: " <> tshow e) $ do
logInfo $ "Serving static site on port " <> tshow port <> " (TLS)"
WT.runTLS (WT.tlsSettings cert key) (mkSettings port) app
Expand Down Expand Up @@ -72,23 +74,44 @@ warpSettings :: W.Settings
warpSettings = W.setGracefulShutdownTimeout (Just 1) W.defaultSettings

staticFiles :: FilePath -> Application
staticFiles root = S.staticApp settings
staticFiles root = S.staticApp settings . changeWellKnownPath
where
settings = (S.defaultFileServerSettings root)
{ S.ssListing = Nothing
}
settings = defSettings {ssListing = Nothing, ssGetMimeType = getMimeType}
defSettings = S.defaultFileServerSettings root
getMimeType f
| WAT.fromPiece (WAT.fileName f) == "apple-app-site-association" = pure "application/json"
| otherwise = (ssGetMimeType defSettings) f
changeWellKnownPath req = case pathInfo req of
".well-known" : rest ->
req
{ pathInfo = "well-known" : rest,
rawPathInfo = "/well-known/" <> B.drop pfxLen (rawPathInfo req)
}
_ -> req
pfxLen = B.length "/.well-known/"

generateSite :: ServerInformation -> Maybe TransportHost -> FilePath -> IO ()
generateSite si onionHost sitePath = do
createDirectoryIfMissing True sitePath
B.writeFile (sitePath </> "index.html") $ serverInformation si onionHost
createDirectoryIfMissing True $ sitePath </> "media"
forM_ E.mediaContent $ \(path, bs) -> B.writeFile (sitePath </> "media" </> path) bs
createDirectoryIfMissing True $ sitePath </> "contact"
B.writeFile (sitePath </> "contact" </> "index.html") E.linkHtml
createDirectoryIfMissing True $ sitePath </> "invitation"
B.writeFile (sitePath </> "invitation" </> "index.html") E.linkHtml
copyDir "media" E.mediaContent
-- `.well-known` path is re-written in changeWellKnownPath,
-- staticApp does not allow hidden folders.
copyDir "well-known" E.wellKnown
createLinkPage "contact"
createLinkPage "invitation"
createLinkPage "a"
createLinkPage "c"
createLinkPage "g"
createLinkPage "i"
logInfo $ "Generated static site contents at " <> tshow sitePath
where
copyDir dir content = do
createDirectoryIfMissing True $ sitePath </> dir
forM_ content $ \(path, s) -> B.writeFile (sitePath </> dir </> path) s
createLinkPage path = do
createDirectoryIfMissing True $ sitePath </> path
B.writeFile (sitePath </> path </> "index.html") E.linkHtml

serverInformation :: ServerInformation -> Maybe TransportHost -> ByteString
serverInformation ServerInformation {config, information} onionHost = render E.indexHtml substs
Expand Down
3 changes: 3 additions & 0 deletions apps/smp-server/web/Static/Embedded.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ linkHtml = $(embedFile "apps/smp-server/static/link.html")

mediaContent :: [(FilePath, ByteString)]
mediaContent = $(embedDir "apps/smp-server/static/media/")

wellKnown :: [(FilePath, ByteString)]
wellKnown = $(embedDir "apps/smp-server/static/.well-known/")
Loading
Loading