Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57052a6011 | ||
|
|
94cc74bb95 | ||
|
|
b38f50ee5e | ||
|
|
b812e6a8d6 |
No files matched your search
Executable
+88
@@ -0,0 +1,88 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
version=$1
|
||||||
|
here=$(pwd)
|
||||||
|
root=${PACKAGES_ROOT:-/var/www/packages.arasaka.software}
|
||||||
|
keep=${FDROID_KEEP:-3}
|
||||||
|
url=https://packages.arasaka.software/fdroid/repo
|
||||||
|
fingerprint=5F52CFF4F52F4E0B6DA6CD044BFCEAF78D1D42DB24F2470602DB7F19CBFDF846
|
||||||
|
id=software.arasaka.meweb
|
||||||
|
apk=$here/releases/$version/MeWeb-$version-android.apk
|
||||||
|
test -f "$apk"
|
||||||
|
if [ -z "${MEWEB_KEYSTORE_B64:-}" ] || [ -z "${MEWEB_KEYSTORE_PASS:-}" ]; then
|
||||||
|
echo "::error::the repository secrets MEWEB_KEYSTORE_B64 and MEWEB_KEYSTORE_PASS are not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
major=$(echo "$version" | cut -d. -f1)
|
||||||
|
minor=$(echo "$version" | cut -d. -f2)
|
||||||
|
patch=$(echo "$version" | cut -d. -f3)
|
||||||
|
code=$((major * 10000 + minor * 100 + patch))
|
||||||
|
|
||||||
|
tools/setup.sh --group fdroid
|
||||||
|
tools=$(cd "$here/tools/fdroid/linux-x64" && pwd -P)
|
||||||
|
pinned=$(sed -n 's/^fdroidserver==\([^ ]*\).*/\1/p' packaging/fdroid/requirements.txt)
|
||||||
|
venv=$tools/fdroidserver-$pinned
|
||||||
|
if ! "$venv/bin/fdroid" --version > /dev/null 2>&1; then
|
||||||
|
rm -rf "$venv"
|
||||||
|
UV_CACHE_DIR=$tools/cache UV_PYTHON_INSTALL_DIR=$tools/python "$tools/uv-x86_64-unknown-linux-gnu/uv" venv -q --python 3.12 "$venv"
|
||||||
|
UV_CACHE_DIR=$tools/cache "$tools/uv-x86_64-unknown-linux-gnu/uv" pip install -q --python "$venv/bin/python" --require-hashes -r packaging/fdroid/requirements.txt
|
||||||
|
fi
|
||||||
|
JAVA_HOME=$(ls -d "$here"/tools/jdk/linux-x64/*/ | head -n 1)
|
||||||
|
ANDROID_HOME=$here/tools/android-sdk
|
||||||
|
PATH=$JAVA_HOME/bin:$PATH
|
||||||
|
export JAVA_HOME ANDROID_HOME PATH
|
||||||
|
|
||||||
|
exec 9>>"$root/.lock"
|
||||||
|
flock -w 2700 9
|
||||||
|
|
||||||
|
keys=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$keys"' EXIT
|
||||||
|
(umask 077 && printf '%s' "$MEWEB_KEYSTORE_B64" | base64 -d > "$keys/meweb.keystore")
|
||||||
|
MEWEB_KEYSTORE=$keys/meweb.keystore
|
||||||
|
export MEWEB_KEYSTORE MEWEB_KEYSTORE_PASS
|
||||||
|
unset MEWEB_KEYSTORE_B64
|
||||||
|
held=$(keytool -J-Duser.language=en -list -v -keystore "$MEWEB_KEYSTORE" -storepass:env MEWEB_KEYSTORE_PASS -alias meweb | sed -n 's/^.*SHA256: *//p' | tr -d ':')
|
||||||
|
test "$held" = "$fingerprint"
|
||||||
|
|
||||||
|
state=$root/.fdroid
|
||||||
|
snap=$state/$(date -u +%Y%m%d%H%M%S)-$version
|
||||||
|
mkdir -p "$snap/repo" "$snap/metadata" "$snap/tmp"
|
||||||
|
if [ -e "$root/fdroid/repo" ]; then
|
||||||
|
prior=$(readlink -f "$root/fdroid/repo")/..
|
||||||
|
for file in "$prior"/repo/*.apk; do
|
||||||
|
[ -e "$file" ] && ln "$file" "$snap/repo/"
|
||||||
|
done
|
||||||
|
cp -a "$prior/metadata/." "$snap/metadata/"
|
||||||
|
cp "$prior/repo/index-v2.json" "$snap/repo/"
|
||||||
|
if [ -f "$prior/tmp/apkcache.json" ]; then cp "$prior/tmp/apkcache.json" "$snap/tmp/"; fi
|
||||||
|
fi
|
||||||
|
cp packaging/fdroid/config.yml "$snap/config.yml"
|
||||||
|
chmod 600 "$snap/config.yml"
|
||||||
|
cp packaging/fdroid/icon.png "$snap/icon.png"
|
||||||
|
cp -r packaging/fdroid/metadata/. "$snap/metadata/"
|
||||||
|
rm -f "$snap/repo/${id}_$code.apk"
|
||||||
|
cp "$apk" "$snap/repo/${id}_$code.apk"
|
||||||
|
(cd "$snap/repo" && ls "$id"_*.apk | sed 's/.*_\([0-9]*\)\.apk$/\1/' | sort -n | head -n "-$keep" | while read -r old; do
|
||||||
|
rm -f "${id}_$old.apk"
|
||||||
|
done)
|
||||||
|
|
||||||
|
(cd "$snap" && "$venv/bin/fdroid" update)
|
||||||
|
rm -rf "$snap/repo/status"
|
||||||
|
chmod -R u=rwX,go=rX "$snap/repo"
|
||||||
|
|
||||||
|
mkdir -p "$root/fdroid"
|
||||||
|
ln -sfn "../.fdroid/$(basename "$snap")/repo" "$root/fdroid/repo.new"
|
||||||
|
mv -T -f "$root/fdroid/repo.new" "$root/fdroid/repo"
|
||||||
|
ls -1d "$state"/*/ | sort | head -n -3 | while read -r old; do
|
||||||
|
find "$old" -maxdepth 0 -mmin +1440 -exec rm -rf {} +
|
||||||
|
done
|
||||||
|
echo "published ${id}_$code.apk in $root/fdroid/repo"
|
||||||
|
|
||||||
|
if [ "$root" = /var/www/packages.arasaka.software ]; then
|
||||||
|
curl -fsS "$url/entry.jar" -o "$keys/entry.jar"
|
||||||
|
signed=$(keytool -J-Duser.language=en -printcert -jarfile "$keys/entry.jar" | sed -n 's/^.*SHA256: *//p' | head -n 1 | tr -d ':')
|
||||||
|
test "$signed" = "$fingerprint"
|
||||||
|
curl -fsS "$url/index-v2.json" | grep -Eq "\"versionCode\": ?$code\b"
|
||||||
|
curl -fsSI "$url/${id}_$code.apk" > /dev/null
|
||||||
|
echo "live at $url: $id $version ($code)"
|
||||||
|
fi
|
||||||
@@ -8,7 +8,7 @@ fi
|
|||||||
echo "VERSION=$version" >> "$GITHUB_ENV"
|
echo "VERSION=$version" >> "$GITHUB_ENV"
|
||||||
echo "COMMIT=$(echo "$GITHUB_SHA" | cut -c1-8)" >> "$GITHUB_ENV"
|
echo "COMMIT=$(echo "$GITHUB_SHA" | cut -c1-8)" >> "$GITHUB_ENV"
|
||||||
keep="$HOME/.cache/meweb"
|
keep="$HOME/.cache/meweb"
|
||||||
for dir in tools/cache tools/jdk tools/packaging tools/android-sdk; do
|
for dir in tools/cache tools/jdk tools/packaging tools/android-sdk tools/fdroid; do
|
||||||
mkdir -p "$keep/$dir"
|
mkdir -p "$keep/$dir"
|
||||||
rm -rf "$dir"
|
rm -rf "$dir"
|
||||||
ln -s "$keep/$dir" "$dir"
|
ln -s "$keep/$dir" "$dir"
|
||||||
|
|||||||
@@ -54,3 +54,10 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
RELEASE_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
RELEASE_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
run: .gitea/scripts/release.sh "v$VERSION" releases/"$VERSION"/*
|
run: .gitea/scripts/release.sh "v$VERSION" releases/"$VERSION"/*
|
||||||
|
|
||||||
|
- name: The APK in the F-Droid repository on packages.arasaka.software
|
||||||
|
if: ${{ github.ref_type == 'tag' }}
|
||||||
|
env:
|
||||||
|
MEWEB_KEYSTORE_B64: ${{ secrets.MEWEB_KEYSTORE_B64 }}
|
||||||
|
MEWEB_KEYSTORE_PASS: ${{ secrets.MEWEB_KEYSTORE_PASS }}
|
||||||
|
run: .gitea/scripts/fdroid.sh "$VERSION"
|
||||||
@@ -17,6 +17,7 @@ appsettings.*.local.json
|
|||||||
/tools/packaging/
|
/tools/packaging/
|
||||||
/tools/android-sdk/
|
/tools/android-sdk/
|
||||||
/tools/cache/
|
/tools/cache/
|
||||||
|
/tools/fdroid/
|
||||||
/tools/logs/
|
/tools/logs/
|
||||||
/.claude/settings.local.json
|
/.claude/settings.local.json
|
||||||
/artifacts/
|
/artifacts/
|
||||||
@@ -173,6 +173,23 @@ The Android release key: alias `meweb`, certificate SHA-256
|
|||||||
`arasaka_repository_known`, or installed copies are treated as edited by hand and left alone. The package owns
|
`arasaka_repository_known`, or installed copies are treated as edited by hand and left alone. The package owns
|
||||||
`/usr/share/arasaka-repository/meweb`, the marker that keeps the repository configured while any Arasaka package
|
`/usr/share/arasaka-repository/meweb`, the marker that keeps the repository configured while any Arasaka package
|
||||||
is installed. The signing key's only copies are that secret and the owner's Nextcloud backup.
|
is installed. The signing key's only copies are that secret and the owner's Nextcloud backup.
|
||||||
|
- **The APK reaches an F-Droid repository on packages.arasaka.software from the same job** (31 Oct 2026), after the
|
||||||
|
release is published, so the repository can lag the release page but never lead it. `.gitea/scripts/fdroid.sh`
|
||||||
|
installs fdroidserver into `tools/fdroid` (cached like the JDK) with uv from `setup.json` and the hash-locked
|
||||||
|
`packaging/fdroid/requirements.txt`, because the box has no `ensurepip` and the apt package would bring 242 others.
|
||||||
|
The environment is made at the cache's real path (`pwd -P`) and rebuilt whenever `fdroid --version` fails: its
|
||||||
|
scripts carry the absolute path they were made at, `tools/fdroid` is a symlink from a workspace that can move, and
|
||||||
|
0.15.1's step failed with `fdroid: not found` on exactly that.
|
||||||
|
It signs the repository with the APK's own key (`MEWEB_KEYSTORE_B64` and `MEWEB_KEYSTORE_PASS`, alias `meweb`), so
|
||||||
|
the F-Droid fingerprint is the certificate's `5F52CFF4…FDF846` and there is no second key to lose; it refuses any
|
||||||
|
other. It builds a new snapshot in
|
||||||
|
`/var/www/packages.arasaka.software/.fdroid/` from the live one (the APKs as hard links, so `rm` then `cp` as above;
|
||||||
|
the metadata, `apkcache.json` and the previous `index-v2.json`, which is where fdroidserver reads each APK's first
|
||||||
|
date), adds this version, keeps the newest three, runs `fdroid update`, deletes `repo/status/` (it names the
|
||||||
|
build machine's paths and `/etc/issue.net`), swaps the `fdroid/repo` link and checks the live signature. The key
|
||||||
|
was already never to be regenerated; now everyone who added the repository trusts only its fingerprint too. `packaging/fdroid/` holds the
|
||||||
|
repository's settings, its icon (the Arasaka emblem) and the app's listing in English and Italian; the download
|
||||||
|
page links to it and to Obtainium (`Endpoints.FDroid`, source `FDroidRepo`).
|
||||||
- **The server cannot ping**: `NoNewPrivileges` drops `ping`'s file capability and `ping_group_range` is closed, so
|
- **The server cannot ping**: `NoNewPrivileges` drops `ping`'s file capability and `ping_group_range` is closed, so
|
||||||
the trace back to a caller uses `tracepath` (UDP, unprivileged) and keeps only public hops outside `Probe:Refuse`,
|
the trace back to a caller uses `tracepath` (UDP, unprivileged) and keeps only public hops outside `Probe:Refuse`,
|
||||||
so the box's own network never reaches an app.
|
so the box's own network never reaches an app.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>0.15.0</Version>
|
<Version>0.15.2</Version>
|
||||||
<Product>me-web?</Product>
|
<Product>me-web?</Product>
|
||||||
<Company>Arasaka di Hvozdikov Yevheniy</Company>
|
<Company>Arasaka di Hvozdikov Yevheniy</Company>
|
||||||
<Copyright>© 2026 Arasaka di Hvozdikov Yevheniy</Copyright>
|
<Copyright>© 2026 Arasaka di Hvozdikov Yevheniy</Copyright>
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ It ends with what that means: a website, reaching home from outside, family phot
|
|||||||
server, a fediverse or blog server, a mail server — possible, possible with a workaround (and which), or can't tell.
|
server, a fediverse or blog server, a mail server — possible, possible with a workaround (and which), or can't tell.
|
||||||
|
|
||||||
At the end you can choose to share your findings, after reading exactly what is sent, to improve the notes on
|
At the end you can choose to share your findings, after reading exactly what is sent, to improve the notes on
|
||||||
providers; you can delete them from the app at any time, and they are deleted after twelve months
|
providers. If you then give the code it returns to the publisher when you ask for help, the publisher reads them to
|
||||||
|
answer you. You can delete them from the app at any time, and they are deleted after twelve months
|
||||||
(<https://meweb.arasaka.software/privacy>).
|
(<https://meweb.arasaka.software/privacy>).
|
||||||
|
|
||||||
Planned: the builds for Mac announced once they have been tried on a real Mac.
|
Planned: the builds for Mac announced once they have been tried on a real Mac.
|
||||||
@@ -53,6 +54,10 @@ import it first with `sudo rpm --import https://packages.arasaka.software/arasak
|
|||||||
is `packaging/arasaka-repository.sh`; it never calls the package manager,
|
is `packaging/arasaka-repository.sh`; it never calls the package manager,
|
||||||
leaves files you edited alone, and removes the repository only when no Arasaka package is left (purge or erase).
|
leaves files you edited alone, and removes the repository only when no Arasaka package is left (purge or erase).
|
||||||
|
|
||||||
|
On Android, the same signed APK is also in an F-Droid repository, so F-Droid, a store like it, or Obtainium can bring
|
||||||
|
the updates: add `https://packages.arasaka.software/fdroid/repo`, which is signed with the same key as the APK. The
|
||||||
|
download page links to both. The app is not in F-Droid's own catalogue, which builds every app from source on F-Droid's servers.
|
||||||
|
|
||||||
## Privacy
|
## Privacy
|
||||||
|
|
||||||
“me-web?” sends nothing anywhere unless a check needs it, and lists every host it contacts ("What this app contacts"
|
“me-web?” sends nothing anywhere unless a check needs it, and lists every host it contacts ("What this app contacts"
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
repo_url: https://packages.arasaka.software/fdroid/repo
|
||||||
|
repo_name: Arasaka
|
||||||
|
repo_description: >-
|
||||||
|
Apps published by Arasaka di Hvozdikov Yevheniy, Busto Arsizio, Italy, such as “me-web?”.
|
||||||
|
Each app here is the same signed file as on its release page.
|
||||||
|
repo_icon: icon.png
|
||||||
|
archive_older: 0
|
||||||
|
repo_keyalias: meweb
|
||||||
|
keystore: {env: MEWEB_KEYSTORE}
|
||||||
|
keystorepass: {env: MEWEB_KEYSTORE_PASS}
|
||||||
|
keypass: {env: MEWEB_KEYSTORE_PASS}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -0,0 +1,10 @@
|
|||||||
|
Categories:
|
||||||
|
- Connectivity
|
||||||
|
- Internet
|
||||||
|
License: AGPL-3.0-only
|
||||||
|
AuthorName: Arasaka di Hvozdikov Yevheniy
|
||||||
|
WebSite: https://meweb.arasaka.software
|
||||||
|
SourceCode: https://git.thepra.dev/Arasaka/MeWeb
|
||||||
|
IssueTracker: https://git.thepra.dev/Arasaka/MeWeb/issues
|
||||||
|
Changelog: https://git.thepra.dev/Arasaka/MeWeb/releases
|
||||||
|
AutoName: me-web?
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
“me-web?” checks your connection and your device and tells you, in plain words, what you could host at home, what stands in the way, and what would fix it. Free software, no telemetry, no account.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
me-web?
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Can you run your own server from here?
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
«me-web?» controlla la sua connessione e il suo dispositivo e le dice, in parole semplici, che cosa potrebbe ospitare a casa, che cosa lo impedisce e che cosa lo risolverebbe. Software libero, niente telemetria, nessun account.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
me-web?
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Può ospitare un server da qui?
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -9,6 +9,8 @@ namespace MeWeb.Server;
|
|||||||
public static class DownloadPage
|
public static class DownloadPage
|
||||||
{
|
{
|
||||||
const string Fingerprint = "5F:52:CF:F4:F5:2F:4E:0B:6D:A6:CD:04:4B:FC:EA:F7:8D:1D:42:DB:24:F2:47:06:02:DB:7F:19:CB:FD:F8:46";
|
const string Fingerprint = "5F:52:CF:F4:F5:2F:4E:0B:6D:A6:CD:04:4B:FC:EA:F7:8D:1D:42:DB:24:F2:47:06:02:DB:7F:19:CB:FD:F8:46";
|
||||||
|
const string ObtainiumApp = $$"""{"id":"software.arasaka.meweb","url":"{{Endpoints.FDroid.Repository}}","author":"Arasaka","name":"me-web?","overrideSource":"FDroidRepo","additionalSettings":"{\"appIdOrName\":\"software.arasaka.meweb\"}"}""";
|
||||||
|
static readonly string Obtainium = Endpoints.FDroid.Obtainium + Uri.EscapeDataString(ObtainiumApp);
|
||||||
|
|
||||||
static readonly Dictionary<string, Dictionary<string, string>> Words = new()
|
static readonly Dictionary<string, Dictionary<string, string>> Words = new()
|
||||||
{
|
{
|
||||||
@@ -20,6 +22,11 @@ public static class DownloadPage
|
|||||||
["None"] = "There is no release to download yet.",
|
["None"] = "There is no release to download yet.",
|
||||||
["Android"] = "Android",
|
["Android"] = "Android",
|
||||||
["AndroidNote"] = "Your phone will ask whether the browser may install apps. The app is signed; its certificate's SHA-256 is",
|
["AndroidNote"] = "Your phone will ask whether the browser may install apps. The app is signed; its certificate's SHA-256 is",
|
||||||
|
["Updates"] = "To get updates without coming back here, add the Arasaka repository to F-Droid (or a store like it), or add the app to Obtainium. Either way you get the same signed file.",
|
||||||
|
["AddFDroid"] = "Add to F-Droid",
|
||||||
|
["AddObtainium"] = "Add to Obtainium",
|
||||||
|
["RepoAddress"] = "The repository's address is",
|
||||||
|
["RepoKey"] = "and it is signed with the same key as the app.",
|
||||||
["Windows"] = "Windows (64-bit)",
|
["Windows"] = "Windows (64-bit)",
|
||||||
["WindowsNote"] = "The file isn't signed with a paid certificate, so Windows may say it protected your PC: choose “More info”, then “Run anyway”.",
|
["WindowsNote"] = "The file isn't signed with a paid certificate, so Windows may say it protected your PC: choose “More info”, then “Run anyway”.",
|
||||||
["Linux"] = "Linux",
|
["Linux"] = "Linux",
|
||||||
@@ -43,6 +50,11 @@ public static class DownloadPage
|
|||||||
["None"] = "Non c'è ancora una versione da scaricare.",
|
["None"] = "Non c'è ancora una versione da scaricare.",
|
||||||
["Android"] = "Android",
|
["Android"] = "Android",
|
||||||
["AndroidNote"] = "Il telefono chiederà se il browser può installare app. L'app è firmata; lo SHA-256 del suo certificato è",
|
["AndroidNote"] = "Il telefono chiederà se il browser può installare app. L'app è firmata; lo SHA-256 del suo certificato è",
|
||||||
|
["Updates"] = "Per ricevere gli aggiornamenti senza tornare qui, aggiunga il repository Arasaka a F-Droid (o a uno store simile), oppure aggiunga l'app a Obtainium. In entrambi i casi riceve lo stesso file firmato.",
|
||||||
|
["AddFDroid"] = "Aggiungere a F-Droid",
|
||||||
|
["AddObtainium"] = "Aggiungere a Obtainium",
|
||||||
|
["RepoAddress"] = "L'indirizzo del repository è",
|
||||||
|
["RepoKey"] = "ed è firmato con la stessa chiave dell'app.",
|
||||||
["Windows"] = "Windows (64 bit)",
|
["Windows"] = "Windows (64 bit)",
|
||||||
["WindowsNote"] = "Il file non è firmato con un certificato a pagamento, quindi Windows può dire di aver protetto il PC: scelga “Ulteriori informazioni”, poi “Esegui comunque”.",
|
["WindowsNote"] = "Il file non è firmato con un certificato a pagamento, quindi Windows può dire di aver protetto il PC: scelga “Ulteriori informazioni”, poi “Esegui comunque”.",
|
||||||
["Linux"] = "Linux",
|
["Linux"] = "Linux",
|
||||||
@@ -76,7 +88,9 @@ public static class DownloadPage
|
|||||||
{
|
{
|
||||||
var version = release.Tag.TrimStart('v');
|
var version = release.Tag.TrimStart('v');
|
||||||
html.Append($"<p class=\"soft\">{E(string.Format(culture, words["Latest"], version, release.PublishedAt.ToString("d MMMM yyyy", culture)))}</p>");
|
html.Append($"<p class=\"soft\">{E(string.Format(culture, words["Latest"], version, release.PublishedAt.ToString("d MMMM yyyy", culture)))}</p>");
|
||||||
Block(html, release, words["Android"], [("android", "APK")], $"{E(words["AndroidNote"])} <code>{Fingerprint}</code>.");
|
Block(html, release, words["Android"], [("android", "APK")], $"{E(words["AndroidNote"])} <code>{Fingerprint}</code>.",
|
||||||
|
$"<p>{E(words["Updates"])}</p><p><a href=\"{E(Endpoints.FDroid.Add)}\">{E(words["AddFDroid"])}</a> · <a href=\"{E(Obtainium)}\">{E(words["AddObtainium"])}</a></p>" +
|
||||||
|
$"<p class=\"soft\">{E(words["RepoAddress"])} <code>{Endpoints.FDroid.Repository}</code> {E(words["RepoKey"])}</p>");
|
||||||
Block(html, release, words["Windows"], [("windows", ".exe")], E(words["WindowsNote"]));
|
Block(html, release, words["Windows"], [("windows", ".exe")], E(words["WindowsNote"]));
|
||||||
var deb = ReleaseFeed.Asset(release, "linux-deb")?.Name;
|
var deb = ReleaseFeed.Asset(release, "linux-deb")?.Name;
|
||||||
var rpm = ReleaseFeed.Asset(release, "linux-rpm")?.Name;
|
var rpm = ReleaseFeed.Asset(release, "linux-rpm")?.Name;
|
||||||
@@ -91,7 +105,7 @@ public static class DownloadPage
|
|||||||
return html.ToString();
|
return html.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Block(StringBuilder html, GiteaRelease release, string title, (string Platform, string Label)[] files, string note)
|
static void Block(StringBuilder html, GiteaRelease release, string title, (string Platform, string Label)[] files, string note, string more = "")
|
||||||
{
|
{
|
||||||
html.Append($"<div class=\"card\"><h2>{E(title)}</h2>");
|
html.Append($"<div class=\"card\"><h2>{E(title)}</h2>");
|
||||||
foreach (var (platform, label) in files)
|
foreach (var (platform, label) in files)
|
||||||
@@ -100,7 +114,7 @@ public static class DownloadPage
|
|||||||
if (asset is null) continue;
|
if (asset is null) continue;
|
||||||
html.Append($"<a class=\"button\" href=\"{Endpoints.Downloads.GET_M_Platform(platform)}\">{E(label)} · {asset.Size / 1048576.0:0} MB</a>");
|
html.Append($"<a class=\"button\" href=\"{Endpoints.Downloads.GET_M_Platform(platform)}\">{E(label)} · {asset.Size / 1048576.0:0} MB</a>");
|
||||||
}
|
}
|
||||||
html.Append($"<p class=\"soft\">{note}</p></div>");
|
html.Append($"<p class=\"soft\">{note}</p>{more}</div>");
|
||||||
}
|
}
|
||||||
|
|
||||||
static string E(string text) => WebUtility.HtmlEncode(text ?? "");
|
static string E(string text) => WebUtility.HtmlEncode(text ?? "");
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ public static class PrivacyPage
|
|||||||
{
|
{
|
||||||
static readonly Dictionary<string, (string Title, string Other, string Publisher, string Footer, string[] Sections)> Texts = new()
|
static readonly Dictionary<string, (string Title, string Other, string Publisher, string Footer, string[] Sections)> Texts = new()
|
||||||
{
|
{
|
||||||
["en"] = ("me-web? · privacy", "Italiano", "Published by Arasaka di Hvozdikov Yevheniy, Busto Arsizio, Italy · VAT IT03929200123", "Last changed 16 October 2026.",
|
["en"] = ("me-web? · privacy", "Italiano", "Published by Arasaka di Hvozdikov Yevheniy, Busto Arsizio, Italy · VAT IT03929200123", "Last changed 31 October 2026.",
|
||||||
[
|
[
|
||||||
"## Who is responsible",
|
"## Who is responsible",
|
||||||
"Arasaka di Hvozdikov Yevheniy, a sole trader in Busto Arsizio (VA), Italy, VAT number IT03929200123, publishes “me-web?” and runs its server, meweb.arasaka.software, on its own hardware in Italy. Questions and requests: through the form at [https://arasaka.software/contact](https://arasaka.software/contact).",
|
"Arasaka di Hvozdikov Yevheniy, a sole trader in Busto Arsizio (VA), Italy, VAT number IT03929200123, publishes “me-web?” and runs its server, meweb.arasaka.software, on its own hardware in Italy. Questions and requests: through the form at [https://arasaka.software/contact](https://arasaka.software/contact).",
|
||||||
@@ -16,17 +16,19 @@ public static class PrivacyPage
|
|||||||
"## The test from outside, only if you agree",
|
"## The test from outside, only if you agree",
|
||||||
"If you choose it in the app, the server connects back to your public address on up to three ports to see whether it reaches the app, and traces the route from the server towards that address, looking up the names of the routers on the way. The results go back to the app and are not stored. If you also choose to open ports, the app asks your router to open them for ten minutes and closes them afterwards.",
|
"If you choose it in the app, the server connects back to your public address on up to three ports to see whether it reaches the app, and traces the route from the server towards that address, looking up the names of the routers on the way. The results go back to the app and are not stored. If you also choose to open ports, the app asks your router to open them for ten minutes and closes them afterwards.",
|
||||||
"## Shared findings, only if you send them",
|
"## Shared findings, only if you send them",
|
||||||
"If you press “Send” after reading exactly what will be sent, the server stores those findings, which include your public addresses, your provider, your router's make and model and the results of the checks, as a file on the same server in Italy. The purpose is to improve the notes on providers in later versions of “me-web?”; only totals without addresses are ever published, after a person has reviewed them, and only for a provider whose findings come from at least five different networks, four in five of them agreeing; the total says how many. The legal basis is your consent (Article 6(1)(a) GDPR). Each submission is deleted automatically after twelve months, or earlier when you delete it in the app, or ask for it with its code (MW-…).",
|
"If you press “Send” after reading exactly what will be sent, the server stores those findings, which include your public addresses, your provider, your router's make and model and the results of the checks, as a file on the same server in Italy. They serve two purposes. The first is to improve the notes on providers in later versions of “me-web?”: only totals without addresses are ever published, after a person has reviewed them, and only for a provider whose findings come from at least five different networks, four in five of them agreeing; the total says how many. The second applies only if you give your code (MW-…) to the publisher yourself, for example when you ask for help with your connection: the publisher reads your findings to answer you where you asked, and never repeats your addresses there. The legal basis is your consent (Article 6(1)(a) GDPR). Each submission is deleted automatically after twelve months, or earlier when you delete it in the app, or ask for it with its code (MW-…).",
|
||||||
"## The STUN servers",
|
"## The STUN servers",
|
||||||
"To see how your router or your provider translates addresses for calls and games, the app sends one short message to stun.nextcloud.com, run by Nextcloud GmbH in Germany, which sees your public address as any server you contact does, and about twenty to stun.meweb.arasaka.software, run by the publisher, some of them two minutes apart to see how long an idle connection stays open.",
|
"To see how your router or your provider translates addresses for calls and games, the app sends one short message to stun.nextcloud.com, run by Nextcloud GmbH in Germany, which sees your public address as any server you contact does, and about twenty to stun.meweb.arasaka.software, run by the publisher, some of them two minutes apart to see how long an idle connection stays open.",
|
||||||
"## Updates on Linux",
|
"## Updates on Linux",
|
||||||
"If you install the Linux package, it adds the Arasaka package repository to your system, and your package manager then checks packages.arasaka.software for updates, as it does with every repository it knows. That server keeps no access log.",
|
"If you install the Linux package, it adds the Arasaka package repository to your system, and your package manager then checks packages.arasaka.software for updates, as it does with every repository it knows. That server keeps no access log.",
|
||||||
|
"## Updates on Android, if you choose them",
|
||||||
|
"If you add the Arasaka repository to F-Droid or a store like it, or add the app to Obtainium, that app checks packages.arasaka.software for updates. That server keeps no access log.",
|
||||||
"## Nothing else",
|
"## Nothing else",
|
||||||
"No cookies, no analytics, no advertising, no crash reports. The app keeps your earlier checks on your device only, and you can forget them in the app.",
|
"No cookies, no analytics, no advertising, no crash reports. The app keeps your earlier checks on your device only, and you can forget them in the app.",
|
||||||
"## Your rights",
|
"## Your rights",
|
||||||
"You can ask for access to, correction or erasure of your data, restrict its use, take it with you, and withdraw your consent at any time, through the form above. You can also complain to the Italian supervisory authority, the Garante per la protezione dei dati personali ([https://www.garanteprivacy.it](https://www.garanteprivacy.it)).",
|
"You can ask for access to, correction or erasure of your data, restrict its use, take it with you, and withdraw your consent at any time, through the form above. You can also complain to the Italian supervisory authority, the Garante per la protezione dei dati personali ([https://www.garanteprivacy.it](https://www.garanteprivacy.it)).",
|
||||||
]),
|
]),
|
||||||
["it"] = ("me-web? · privacy", "English", "Pubblicato da Arasaka di Hvozdikov Yevheniy, Busto Arsizio · P.IVA 03929200123", "Ultima modifica 16 ottobre 2026.",
|
["it"] = ("me-web? · privacy", "English", "Pubblicato da Arasaka di Hvozdikov Yevheniy, Busto Arsizio · P.IVA 03929200123", "Ultima modifica 31 ottobre 2026.",
|
||||||
[
|
[
|
||||||
"## Chi è responsabile",
|
"## Chi è responsabile",
|
||||||
"Arasaka di Hvozdikov Yevheniy, ditta individuale di Busto Arsizio (VA), P.IVA 03929200123, pubblica «me-web?» e gestisce il suo server, meweb.arasaka.software, su hardware proprio in Italia. Domande e richieste: con il modulo su [https://arasaka.software/it/contatti](https://arasaka.software/it/contatti).",
|
"Arasaka di Hvozdikov Yevheniy, ditta individuale di Busto Arsizio (VA), P.IVA 03929200123, pubblica «me-web?» e gestisce il suo server, meweb.arasaka.software, su hardware proprio in Italia. Domande e richieste: con il modulo su [https://arasaka.software/it/contatti](https://arasaka.software/it/contatti).",
|
||||||
@@ -35,11 +37,13 @@ public static class PrivacyPage
|
|||||||
"## La prova da fuori, solo se lei è d'accordo",
|
"## La prova da fuori, solo se lei è d'accordo",
|
||||||
"Se lo sceglie nell'app, il server si ricollega al suo indirizzo pubblico su al massimo tre porte per vedere se raggiunge l'app, e traccia il percorso dal server verso quell'indirizzo, cercando i nomi dei router lungo la strada. I risultati tornano all'app e non vengono conservati. Se sceglie anche di aprire le porte, l'app chiede al router di aprirle per dieci minuti e poi le richiude.",
|
"Se lo sceglie nell'app, il server si ricollega al suo indirizzo pubblico su al massimo tre porte per vedere se raggiunge l'app, e traccia il percorso dal server verso quell'indirizzo, cercando i nomi dei router lungo la strada. I risultati tornano all'app e non vengono conservati. Se sceglie anche di aprire le porte, l'app chiede al router di aprirle per dieci minuti e poi le richiude.",
|
||||||
"## I risultati condivisi, solo se li invia",
|
"## I risultati condivisi, solo se li invia",
|
||||||
"Se preme «Invia» dopo aver letto esattamente che cosa verrà inviato, il server conserva quei risultati, che comprendono i suoi indirizzi pubblici, l'operatore, marca e modello del router e gli esiti delle verifiche, come file sullo stesso server in Italia. Lo scopo è migliorare le note sugli operatori nelle prossime versioni di «me-web?»; si pubblicano solo totali senza indirizzi, dopo la revisione di una persona, e solo per un operatore i cui risultati vengono da almeno cinque reti diverse, d'accordo almeno quattro volte su cinque; il totale dice quante. La base giuridica è il suo consenso (art. 6, par. 1, lett. a GDPR). Ogni invio viene cancellato automaticamente dopo dodici mesi, oppure prima, quando lo cancella nell'app o lo chiede indicando il suo codice (MW-…).",
|
"Se preme «Invia» dopo aver letto esattamente che cosa verrà inviato, il server conserva quei risultati, che comprendono i suoi indirizzi pubblici, l'operatore, marca e modello del router e gli esiti delle verifiche, come file sullo stesso server in Italia. Servono a due scopi. Il primo è migliorare le note sugli operatori nelle prossime versioni di «me-web?»: si pubblicano solo totali senza indirizzi, dopo la revisione di una persona, e solo per un operatore i cui risultati vengono da almeno cinque reti diverse, d'accordo almeno quattro volte su cinque; il totale dice quante. Il secondo vale solo se è lei a dare il suo codice (MW-…) all'editore, per esempio quando chiede aiuto per la sua connessione: l'editore legge i suoi risultati per risponderle dove ha chiesto, e lì non riporta mai i suoi indirizzi. La base giuridica è il suo consenso (art. 6, par. 1, lett. a GDPR). Ogni invio viene cancellato automaticamente dopo dodici mesi, oppure prima, quando lo cancella nell'app o lo chiede indicando il suo codice (MW-…).",
|
||||||
"## I server STUN",
|
"## I server STUN",
|
||||||
"Per vedere come il router o l'operatore traducono gli indirizzi per chiamate e giochi, l'app invia un breve messaggio a stun.nextcloud.com, gestito da Nextcloud GmbH in Germania, che vede il suo indirizzo pubblico come qualsiasi server che lei contatta, e una ventina a stun.meweb.arasaka.software, gestito dall'editore, alcuni a due minuti di distanza per vedere quanto resta aperta una connessione inattiva.",
|
"Per vedere come il router o l'operatore traducono gli indirizzi per chiamate e giochi, l'app invia un breve messaggio a stun.nextcloud.com, gestito da Nextcloud GmbH in Germania, che vede il suo indirizzo pubblico come qualsiasi server che lei contatta, e una ventina a stun.meweb.arasaka.software, gestito dall'editore, alcuni a due minuti di distanza per vedere quanto resta aperta una connessione inattiva.",
|
||||||
"## Gli aggiornamenti su Linux",
|
"## Gli aggiornamenti su Linux",
|
||||||
"Se installa il pacchetto per Linux, questo aggiunge al sistema il repository dei pacchetti Arasaka, e il gestore dei pacchetti controlla poi gli aggiornamenti su packages.arasaka.software, come fa con ogni repository che conosce. Quel server non tiene registri di accesso.",
|
"Se installa il pacchetto per Linux, questo aggiunge al sistema il repository dei pacchetti Arasaka, e il gestore dei pacchetti controlla poi gli aggiornamenti su packages.arasaka.software, come fa con ogni repository che conosce. Quel server non tiene registri di accesso.",
|
||||||
|
"## Gli aggiornamenti su Android, se li sceglie",
|
||||||
|
"Se aggiunge il repository Arasaka a F-Droid o a uno store simile, oppure aggiunge l'app a Obtainium, quell'app controlla gli aggiornamenti su packages.arasaka.software. Quel server non tiene registri di accesso.",
|
||||||
"## Nient'altro",
|
"## Nient'altro",
|
||||||
"Niente cookie, niente statistiche, niente pubblicità, niente rapporti sugli arresti anomali. L'app conserva le verifiche precedenti solo sul suo dispositivo, e può dimenticarle dall'app.",
|
"Niente cookie, niente statistiche, niente pubblicità, niente rapporti sugli arresti anomali. L'app conserva le verifiche precedenti solo sul suo dispositivo, e può dimenticarle dall'app.",
|
||||||
"## I suoi diritti",
|
"## I suoi diritti",
|
||||||
|
|||||||
@@ -74,4 +74,12 @@ public static class Endpoints
|
|||||||
public const string Releases = $"{Origin}/{Repository}/releases";
|
public const string Releases = $"{Origin}/{Repository}/releases";
|
||||||
public const string Source = $"{Origin}/{Repository}";
|
public const string Source = $"{Origin}/{Repository}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class FDroid
|
||||||
|
{
|
||||||
|
public const string Repository = "https://packages.arasaka.software/fdroid/repo";
|
||||||
|
public const string Fingerprint = "5F52CFF4F52F4E0B6DA6CD044BFCEAF78D1D42DB24F2470602DB7F19CBFDF846";
|
||||||
|
public const string Add = $"{Repository}?fingerprint={Fingerprint}";
|
||||||
|
public const string Obtainium = "obtainium://app/";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -47,6 +47,18 @@
|
|||||||
"kind": "tar",
|
"kind": "tar",
|
||||||
"dest": "tools/jdk/osx-arm64",
|
"dest": "tools/jdk/osx-arm64",
|
||||||
"check": "tools/jdk/osx-arm64/jdk-21.0.12+8/Contents/Home/bin/java"
|
"check": "tools/jdk/osx-arm64/jdk-21.0.12+8/Contents/Home/bin/java"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "uv",
|
||||||
|
"group": "fdroid",
|
||||||
|
"version": "0.13.1",
|
||||||
|
"license": "MIT or Apache-2.0 (build tool, not distributed)",
|
||||||
|
"rid": "linux-x64",
|
||||||
|
"url": "https://github.com/astral-sh/uv/releases/download/0.13.1/uv-x86_64-unknown-linux-gnu.tar.gz",
|
||||||
|
"sha256": "eadd9d27c134ab5ac1ffd4473b97a741407f3ea238288f03121fc4deddf90220",
|
||||||
|
"kind": "tar",
|
||||||
|
"dest": "tools/fdroid/linux-x64",
|
||||||
|
"check": "tools/fdroid/linux-x64/uv-x86_64-unknown-linux-gnu/uv"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Executable
+4
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
. "$(dirname "$0")/sdk.sh"
|
||||||
|
exec dotnet run tools/setup.cs -- "$@"
|
||||||
Reference in new issue
Block a user