Compare commits
8
Commits
e752d08ebc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bbfd7d455 | ||
|
|
d0832013fe | ||
|
|
b79fdb8bab | ||
|
|
8d717e0037 | ||
|
|
c2f13d6a1a | ||
|
|
afb39fac20 | ||
|
|
b514dab62a | ||
|
|
2d7d8952ab |
+1
-1
@@ -75,7 +75,7 @@ APP_NAME=ihasmail
|
||||
# you have patched it, point this at your own tree. Shown on the sign-in page
|
||||
# and in Settings > About. INBUXA's webmail is itself a modified ihasmail, so
|
||||
# the default is this fork.
|
||||
SOURCE_URL=https://github.com/inbuxa/ihasmail-inbuxa
|
||||
SOURCE_URL=https://git.coffeylabs.org/inbuxa/ihasmail-inbuxa
|
||||
|
||||
# ---- Settings this installation decides (all optional) ----
|
||||
#
|
||||
|
||||
+100
-8
@@ -2,14 +2,15 @@
|
||||
# GitLab (2026-09-22). Gitea reads .gitea/workflows and ignores .github/ once
|
||||
# this directory exists; .github/workflows stays as it was for GitHub.
|
||||
#
|
||||
# There is deliberately no publish job, although publish.yml is in the tree.
|
||||
# Every tag in this repository is one of ihasmail's own upstream tags, the
|
||||
# same commits, and at those tags publish.yml pushed to ihasmail's image, not
|
||||
# an INBUXA one. A tag-driven publish here would ship plain ihasmail under the
|
||||
# INBUXA name the moment upstream tags reached this project -- which happened
|
||||
# once, by hand, and was deleted. Add one back only with a release scheme that
|
||||
# produces tags this repository alone has.
|
||||
#
|
||||
# Releases are cut by pushing a tag named `inbuxa-v<version>`, where
|
||||
# <version> is what scripts/version.mjs says for the tagged commit with the
|
||||
# `+` turned into `-` (e.g. inbuxa-v2026.9.22-g1a2b3c4). The prefix matters:
|
||||
# this repository carries upstream ihasmail's own `v...` tags, on commits it
|
||||
# shares with upstream, and a publish keyed on `v*` would ship plain ihasmail
|
||||
# under the INBUXA name the moment one arrived. Only `inbuxa-v` tags publish.
|
||||
# A tag publishes only if it names its own commit's version and that commit is
|
||||
# on main. There is no release schedule yet; tags are cut by hand.
|
||||
|
||||
# Every job runs in an image pinned by digest (tag in the trailing comment),
|
||||
# and the only action used is coffey-labs/actions/checkout pinned by SHA. The
|
||||
# instance resolves short `uses:` against itself, never GitHub, so nothing
|
||||
@@ -85,3 +86,94 @@ jobs:
|
||||
tag="ihasmail:ci-$(echo "$GITHUB_SHA" | cut -c1-8)"
|
||||
docker build -t "$tag" .
|
||||
docker image rm "$tag"
|
||||
|
||||
# ----------------------------------------------------------- release ------
|
||||
# Only for `inbuxa-v` tags (see the top of this file). The tag has to name
|
||||
# its own commit's version, so the image, the release and the About screen
|
||||
# all agree, and the commit has to be on main, so a release never describes
|
||||
# code that was not reviewed onto the default branch.
|
||||
version:
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/inbuxa-v') }}
|
||||
runs-on: light
|
||||
container:
|
||||
image: node:26-bookworm-slim@sha256:582460f614631b59b824ac6020533b9bf339c7fdf3a6d7db31abb6b4065f0212 # 26-bookworm-slim
|
||||
outputs:
|
||||
version: ${{ steps.v.outputs.VERSION }}
|
||||
docker_tag: ${{ steps.v.outputs.DOCKER_TAG }}
|
||||
steps:
|
||||
- uses: coffey-labs/actions/checkout@fab0c4d45e0162963965f1555df27b7bed5e20ec
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- id: v
|
||||
shell: bash
|
||||
env:
|
||||
TAG: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
V="$(node scripts/version.mjs)"
|
||||
want="inbuxa-v${V/+/-}"
|
||||
[ "$TAG" = "$want" ] || { echo "!! $TAG does not name this commit's version; expected $want"; exit 1; }
|
||||
git merge-base --is-ancestor "$(git rev-parse "${TAG}^{commit}")" origin/main \
|
||||
|| { echo "!! $TAG is not on main"; exit 1; }
|
||||
echo "VERSION=$V" >> "$GITHUB_OUTPUT"
|
||||
echo "DOCKER_TAG=${V/+/-}" >> "$GITHUB_OUTPUT"
|
||||
echo "VERSION=$V DOCKER_TAG=${V/+/-}"
|
||||
|
||||
# Multi-arch image at <REGISTRY>/inbuxa/ihasmail-inbuxa, then the release.
|
||||
# arm64 is built under QEMU on this amd64 host, which is slow but fine for
|
||||
# a hand-cut release. PACKAGE_TOKEN (jcoffey-dev, write:package) logs in:
|
||||
# the job's own token is refused by the container registry. The release is
|
||||
# created last, so a release on the page always has its image behind it.
|
||||
publish:
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/inbuxa-v') }}
|
||||
needs: [node, version]
|
||||
runs-on: docker
|
||||
container:
|
||||
image: docker:28-cli@sha256:625d9431a9f54c5a2bc90f24f0e1c3d55b1349fd857dd85035f98c2c9acbdd4d # 28-cli
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
env:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
REGISTRY: ${{ vars.REGISTRY }}
|
||||
IMAGE: ${{ vars.REGISTRY }}/${{ github.repository }}
|
||||
VERSION: ${{ needs.version.outputs.version }}
|
||||
DOCKER_TAG: ${{ needs.version.outputs.docker_tag }}
|
||||
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
|
||||
steps:
|
||||
- uses: coffey-labs/actions/checkout@fab0c4d45e0162963965f1555df27b7bed5e20ec
|
||||
- run: |
|
||||
test -n "$REGISTRY" && test -n "$VERSION" && test -n "$DOCKER_TAG"
|
||||
test -n "$PACKAGE_TOKEN" || { echo "PACKAGE_TOKEN secret is not set on this repository" >&2; exit 1; }
|
||||
echo "$PACKAGE_TOKEN" | docker login -u jcoffey-dev --password-stdin "$REGISTRY"
|
||||
docker run --privileged --rm tonistiigi/binfmt --install arm64
|
||||
docker buildx create --use --name gitea-builder --driver docker-container || docker buildx use gitea-builder
|
||||
- run: |
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--build-arg IHASMAIL_VERSION="$VERSION" \
|
||||
--provenance=false --sbom=false \
|
||||
--tag "$IMAGE:$DOCKER_TAG" \
|
||||
--tag "$IMAGE:latest" \
|
||||
--push .
|
||||
docker buildx imagetools inspect "$IMAGE:$DOCKER_TAG"
|
||||
# Show the package on the repository's Packages tab. Idempotent.
|
||||
- run: |
|
||||
apk add --no-cache -q curl
|
||||
curl -fsS -o /dev/null -X POST -H "Authorization: token $PACKAGE_TOKEN" \
|
||||
"$CI_SERVER_INTERNAL/api/v1/packages/${GITHUB_REPOSITORY%%/*}/container/${GITHUB_REPOSITORY#*/}/-/link/${GITHUB_REPOSITORY#*/}" \
|
||||
|| echo "package already linked (or link refused); not fatal"
|
||||
# The release, on the internal address. The job's own token may create
|
||||
# releases; a tag it creates would not start a workflow, but this one
|
||||
# already exists.
|
||||
- env:
|
||||
TAG: ${{ github.ref_name }}
|
||||
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -eu
|
||||
body="INBUXA webmail $VERSION.\n\nImage: \`$IMAGE:$DOCKER_TAG\` (linux/amd64, linux/arm64), also tagged \`latest\`."
|
||||
curl -fsS -o /dev/null -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
||||
--data "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\",\"body\":\"$body\"}" \
|
||||
"$CI_SERVER_INTERNAL/api/v1/repos/$GITHUB_REPOSITORY/releases"
|
||||
echo "release $TAG created"
|
||||
- if: always()
|
||||
run: docker logout "$REGISTRY" || true
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ By participating in this project, you agree to treat other contributors with res
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
Before opening a new issue, please search [existing issues](https://github.com/Coffey-Labs/ihasmail/issues) to see if it's already been reported. When filing a bug report, include:
|
||||
Before opening a new issue, please search [existing issues](https://git.coffeylabs.org/coffey-labs/ihasmail/issues) to see if it's already been reported. When filing a bug report, include:
|
||||
|
||||
- A clear, descriptive title
|
||||
- Steps to reproduce the issue
|
||||
|
||||
@@ -70,7 +70,7 @@ docker compose up --build -d
|
||||
## Source code
|
||||
|
||||
INBUXA webmail is a modified ihasmail, so the AGPL's offer is this fork:
|
||||
<https://github.com/inbuxa/ihasmail-inbuxa>. The sign-in page and Settings ›
|
||||
<https://git.coffeylabs.org/inbuxa/ihasmail-inbuxa>. The sign-in page and Settings ›
|
||||
About link there, beside the version, which names the commit the running build
|
||||
came from.
|
||||
|
||||
@@ -94,7 +94,7 @@ Architecture, the mock's switches and how versions are numbered are in
|
||||
|
||||
## Built on ihasmail
|
||||
|
||||
The INBUXA webmail is built on [ihasmail](https://github.com/Coffey-Labs/ihasmail),
|
||||
The INBUXA webmail is built on [ihasmail](https://git.coffeylabs.org/coffey-labs/ihasmail),
|
||||
Coffey Labs' own webmail, which stays an independent product. The public
|
||||
repository is the remote `ihasmail`, fetch-only, and its `main` is merged in to
|
||||
keep up. Nothing here is pushed there.
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ services:
|
||||
APP_SECRET: ${APP_SECRET:?set APP_SECRET in .env (openssl rand -base64 48)}
|
||||
APP_NAME: ${APP_NAME:-ihasmail}
|
||||
BASE_PATH: ${BASE_PATH:-}
|
||||
SOURCE_URL: ${SOURCE_URL:-https://github.com/inbuxa/ihasmail-inbuxa}
|
||||
SOURCE_URL: ${SOURCE_URL:-https://git.coffeylabs.org/inbuxa/ihasmail-inbuxa}
|
||||
TRUST_PROXY: "1"
|
||||
IMAGE_PROXY: "1"
|
||||
volumes:
|
||||
|
||||
@@ -278,7 +278,7 @@ if (oauthClientSecret && !publicUrl) {
|
||||
|
||||
export const config = {
|
||||
isProd,
|
||||
appName: env("APP_NAME", "INBUXA"),
|
||||
appName: env("APP_NAME", "inbuxa"),
|
||||
settingsPolicy: readSettingsPolicy(),
|
||||
/**
|
||||
* What this build calls itself: `2.16.57`. Set by the image build from
|
||||
@@ -295,7 +295,7 @@ export const config = {
|
||||
* ihasmail should point this at their own tree. ihasmail-inbuxa is itself
|
||||
* such a tree, so the default is INBUXA's fork.
|
||||
*/
|
||||
sourceUrl: env("SOURCE_URL", "https://github.com/inbuxa/ihasmail-inbuxa"),
|
||||
sourceUrl: env("SOURCE_URL", "https://git.coffeylabs.org/inbuxa/ihasmail-inbuxa"),
|
||||
host: env("HOST", "0.0.0.0"),
|
||||
port: int("PORT", 8080),
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "INBUXA",
|
||||
"short_name": "INBUXA",
|
||||
"description": "INBUXA webmail",
|
||||
"name": "inbuxa",
|
||||
"short_name": "inbuxa",
|
||||
"description": "inbuxa webmail",
|
||||
"_comment": "JSON has no comments, so: every URL below is relative on purpose. Manifest members resolve against the manifest's own address, so these follow BASE_PATH with nothing substituted into them at build time. Root-absolute values pinned the installed app, its scope and its shortcuts to the domain root whatever the mount was.",
|
||||
"_comment_id": "There is deliberately no `id`. It is the one member NOT resolved against this file's address -- the spec resolves it against the origin of start_url, so `./`, `mail` and `/mail` all mean the same thing at the domain root and none of them can name a subpath mount. Adding one would therefore break the same thing the note above describes. Worse, the default id IS start_url, which is already mount-correct: writing an id now would give every installed copy a new identity and orphan it as a second app rather than updating it. If one is ever wanted it has to be substituted at build time from BASE_PATH, and the changeover costs everybody their install.",
|
||||
"start_url": "mail",
|
||||
|
||||
@@ -12,9 +12,9 @@ import { useSession } from "@/store/session";
|
||||
* One constant rather than the string written out at each of them, because
|
||||
* three copies of a default is how two of them end up stale.
|
||||
*/
|
||||
// ihasmail-inbuxa: INBUXA's webmail goes by INBUXA, so it can't be taken for
|
||||
// ihasmail-inbuxa: inbuxa's webmail goes by inbuxa, so it can't be taken for
|
||||
// public ihasmail. APP_NAME still names a deployment whatever it likes.
|
||||
export const DEFAULT_APP_NAME = "INBUXA";
|
||||
export const DEFAULT_APP_NAME = "inbuxa";
|
||||
/**
|
||||
* What this instance calls itself, right now.
|
||||
*
|
||||
|
||||
@@ -49,7 +49,7 @@ export const UI_LANGUAGES: readonly UiLanguage[] = [
|
||||
];
|
||||
|
||||
/** Where to report a bad translation. Beta languages depend on it. */
|
||||
export const TRANSLATION_ISSUE_URL = "https://github.com/Coffey-Labs/ihasmail/issues/new?title=Translation%3A%20";
|
||||
export const TRANSLATION_ISSUE_URL = "https://git.coffeylabs.org/coffey-labs/ihasmail/issues/new?title=Translation%3A%20";
|
||||
|
||||
export const DEFAULT_UI_LANGUAGE = "en";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { withBase } from "../basePath";
|
||||
|
||||
let baseTitle = "INBUXA";
|
||||
let baseTitle = "inbuxa";
|
||||
let faviconCanvas: HTMLCanvasElement | null = null;
|
||||
let baseFavicon: HTMLImageElement | null = null;
|
||||
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
* ihasmail-inbuxa: INBUXA runs a modified ihasmail, so the offer is INBUXA's
|
||||
* fork and not the project it came from.
|
||||
*/
|
||||
export const DEFAULT_SOURCE_URL = "https://github.com/inbuxa/ihasmail-inbuxa";
|
||||
export const DEFAULT_SOURCE_URL = "https://git.coffeylabs.org/inbuxa/ihasmail-inbuxa";
|
||||
|
||||
@@ -147,8 +147,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "Die Zahlen, die Ihre Rolle sehen darf, so wie der Server sie meldet.",
|
||||
"Nothing to show": "Nichts anzuzeigen",
|
||||
"Could not be loaded": "Konnte nicht geladen werden",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "Detaillierte Metriken, die Zustellwarteschlange, Protokolle und Servereinstellungen finden Sie in INBUXA Admin.",
|
||||
"Open INBUXA Admin": "INBUXA Admin öffnen",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "Detaillierte Metriken, die Zustellwarteschlange, Protokolle und Servereinstellungen finden Sie in inbuxa Admin.",
|
||||
"Open inbuxa Admin": "inbuxa Admin öffnen",
|
||||
"Default group role": "Standardrolle für Gruppen",
|
||||
"A group needs an address.": "Eine Gruppe braucht eine Adresse.",
|
||||
"New group": "Neue Gruppe",
|
||||
@@ -220,7 +220,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "Der Mailserver vergibt diese Rolle standardmäßig an {kinds}. Eine Änderung betrifft alle, die sie auf diesem Weg haben.",
|
||||
"Builds on": "Baut auf",
|
||||
"Permissions": "Berechtigungen",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "Der Mailserver vergibt diese Rolle standardmäßig, daher kann sie nicht gelöscht werden. Ändern Sie zuerst die Standardwerte in INBUXA Admin.",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "Der Mailserver vergibt diese Rolle standardmäßig, daher kann sie nicht gelöscht werden. Ändern Sie zuerst die Standardwerte in inbuxa Admin.",
|
||||
"This role carries permissions yours doesn't.": "Diese Rolle hat Berechtigungen, die Ihre nicht hat.",
|
||||
"Create role": "Rolle anlegen",
|
||||
"builds on this one": "baut auf dieser auf",
|
||||
|
||||
@@ -139,8 +139,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "Las cifras que su rol puede ver, tal como las informa el servidor.",
|
||||
"Nothing to show": "Nada que mostrar",
|
||||
"Could not be loaded": "No se pudo cargar",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "Las métricas detalladas, la cola de entrega, los registros y los ajustes del servidor están en INBUXA Admin.",
|
||||
"Open INBUXA Admin": "Abrir INBUXA Admin",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "Las métricas detalladas, la cola de entrega, los registros y los ajustes del servidor están en inbuxa Admin.",
|
||||
"Open inbuxa Admin": "Abrir inbuxa Admin",
|
||||
"Default group role": "Rol de grupo predeterminado",
|
||||
"A group needs an address.": "Un grupo necesita una dirección.",
|
||||
"New group": "Nuevo grupo",
|
||||
@@ -212,7 +212,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "El servidor de correo asigna este rol de forma predeterminada a {kinds}. Un cambio aquí afecta a todos los que lo tienen así.",
|
||||
"Builds on": "Se basa en",
|
||||
"Permissions": "Permisos",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "El servidor de correo asigna este rol de forma predeterminada, así que no se puede eliminar. Cambie primero los valores predeterminados en INBUXA Admin.",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "El servidor de correo asigna este rol de forma predeterminada, así que no se puede eliminar. Cambie primero los valores predeterminados en inbuxa Admin.",
|
||||
"This role carries permissions yours doesn't.": "Este rol tiene permisos que el suyo no tiene.",
|
||||
"Create role": "Crear rol",
|
||||
"builds on this one": "se basa en este",
|
||||
|
||||
@@ -144,8 +144,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "Les chiffres que votre rôle permet de voir, tels que le serveur les indique.",
|
||||
"Nothing to show": "Rien à afficher",
|
||||
"Could not be loaded": "Chargement impossible",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "Les métriques détaillées, la file de distribution, les journaux et les réglages du serveur se trouvent dans INBUXA Admin.",
|
||||
"Open INBUXA Admin": "Ouvrir INBUXA Admin",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "Les métriques détaillées, la file de distribution, les journaux et les réglages du serveur se trouvent dans inbuxa Admin.",
|
||||
"Open inbuxa Admin": "Ouvrir inbuxa Admin",
|
||||
"Default group role": "Rôle de groupe par défaut",
|
||||
"A group needs an address.": "Un groupe a besoin d’une adresse.",
|
||||
"New group": "Nouveau groupe",
|
||||
@@ -217,7 +217,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "Le serveur de messagerie attribue ce rôle par défaut à {kinds}. Une modification ici s’applique à tous ceux qui l’ont ainsi.",
|
||||
"Builds on": "S’appuie sur",
|
||||
"Permissions": "Autorisations",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "Le serveur de messagerie attribue ce rôle par défaut : il ne peut donc pas être supprimé. Modifiez d’abord les valeurs par défaut dans INBUXA Admin.",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "Le serveur de messagerie attribue ce rôle par défaut : il ne peut donc pas être supprimé. Modifiez d’abord les valeurs par défaut dans inbuxa Admin.",
|
||||
"This role carries permissions yours doesn't.": "Ce rôle comporte des autorisations que le vôtre n’a pas.",
|
||||
"Create role": "Créer le rôle",
|
||||
"builds on this one": "s’appuie sur celui-ci",
|
||||
|
||||
@@ -138,8 +138,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "あなたのロールで見られる数値を、サーバーの報告どおりに表示します。",
|
||||
"Nothing to show": "表示するものはありません",
|
||||
"Could not be loaded": "読み込めませんでした",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "詳細なメトリクス、配信キュー、ログ、サーバー設定は INBUXA Admin にあります。",
|
||||
"Open INBUXA Admin": "INBUXA Admin を開く",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "詳細なメトリクス、配信キュー、ログ、サーバー設定は inbuxa Admin にあります。",
|
||||
"Open inbuxa Admin": "inbuxa Admin を開く",
|
||||
"Default group role": "グループの既定ロール",
|
||||
"A group needs an address.": "グループにはアドレスが必要です。",
|
||||
"New group": "新しいグループ",
|
||||
@@ -211,7 +211,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "メールサーバーはこのロールを既定で {kinds} に付与します。ここでの変更は、この方法でロールを持つ全員に反映されます。",
|
||||
"Builds on": "継承元",
|
||||
"Permissions": "権限",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "メールサーバーがこのロールを既定で付与するため、削除できません。先に INBUXA Admin で既定値を変更してください。",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "メールサーバーがこのロールを既定で付与するため、削除できません。先に inbuxa Admin で既定値を変更してください。",
|
||||
"This role carries permissions yours doesn't.": "このロールにはあなたのロールにない権限があります。",
|
||||
"Create role": "ロールを作成",
|
||||
"builds on this one": "このロールを継承しています",
|
||||
|
||||
@@ -134,8 +134,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "De cijfers die uw rol mag zien, zoals de server ze meldt.",
|
||||
"Nothing to show": "Niets om te tonen",
|
||||
"Could not be loaded": "Kon niet worden geladen",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "Gedetailleerde statistieken, de bezorgwachtrij, logboeken en serverinstellingen vindt u in INBUXA Admin.",
|
||||
"Open INBUXA Admin": "INBUXA Admin openen",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "Gedetailleerde statistieken, de bezorgwachtrij, logboeken en serverinstellingen vindt u in inbuxa Admin.",
|
||||
"Open inbuxa Admin": "inbuxa Admin openen",
|
||||
"Default group role": "Standaardrol voor groepen",
|
||||
"A group needs an address.": "Een groep heeft een adres nodig.",
|
||||
"New group": "Nieuwe groep",
|
||||
@@ -207,7 +207,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "De mailserver geeft deze rol standaard aan {kinds}. Een wijziging hier geldt voor iedereen die hem zo heeft.",
|
||||
"Builds on": "Bouwt voort op",
|
||||
"Permissions": "Rechten",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "De mailserver geeft standaard deze rol, dus hij kan niet worden verwijderd. Wijzig eerst de standaardwaarden in INBUXA Admin.",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "De mailserver geeft standaard deze rol, dus hij kan niet worden verwijderd. Wijzig eerst de standaardwaarden in inbuxa Admin.",
|
||||
"This role carries permissions yours doesn't.": "Deze rol heeft rechten die uw rol niet heeft.",
|
||||
"Create role": "Rol aanmaken",
|
||||
"builds on this one": "bouwt voort op deze",
|
||||
|
||||
@@ -142,8 +142,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "Os números que sua função pode ver, como o servidor os informa.",
|
||||
"Nothing to show": "Nada para mostrar",
|
||||
"Could not be loaded": "Não foi possível carregar",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "Métricas detalhadas, a fila de entrega, os registros e as configurações do servidor ficam no INBUXA Admin.",
|
||||
"Open INBUXA Admin": "Abrir o INBUXA Admin",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "Métricas detalhadas, a fila de entrega, os registros e as configurações do servidor ficam no inbuxa Admin.",
|
||||
"Open inbuxa Admin": "Abrir o inbuxa Admin",
|
||||
"Default group role": "Função padrão de grupo",
|
||||
"A group needs an address.": "Um grupo precisa de um endereço.",
|
||||
"New group": "Novo grupo",
|
||||
@@ -215,7 +215,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "O servidor de e-mail atribui esta função por padrão a {kinds}. Uma alteração aqui vale para todos que a têm dessa forma.",
|
||||
"Builds on": "Baseia-se em",
|
||||
"Permissions": "Permissões",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "O servidor de e-mail atribui esta função por padrão, então ela não pode ser excluída. Altere primeiro os padrões no INBUXA Admin.",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "O servidor de e-mail atribui esta função por padrão, então ela não pode ser excluída. Altere primeiro os padrões no inbuxa Admin.",
|
||||
"This role carries permissions yours doesn't.": "Esta função tem permissões que a sua não tem.",
|
||||
"Create role": "Criar função",
|
||||
"builds on this one": "baseia-se nesta",
|
||||
|
||||
@@ -141,8 +141,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "Показатели, доступные вашей роли, в том виде, в каком их сообщает сервер.",
|
||||
"Nothing to show": "Нечего показать",
|
||||
"Could not be loaded": "Не удалось загрузить",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "Подробные метрики, очередь доставки, журналы и настройки сервера находятся в INBUXA Admin.",
|
||||
"Open INBUXA Admin": "Открыть INBUXA Admin",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "Подробные метрики, очередь доставки, журналы и настройки сервера находятся в inbuxa Admin.",
|
||||
"Open inbuxa Admin": "Открыть inbuxa Admin",
|
||||
"Default group role": "Роль группы по умолчанию",
|
||||
"A group needs an address.": "Группе нужен адрес.",
|
||||
"New group": "Новая группа",
|
||||
@@ -214,7 +214,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "Почтовый сервер по умолчанию выдаёт эту роль: {kinds}. Изменение здесь затронет всех, кто получил её так.",
|
||||
"Builds on": "Основана на",
|
||||
"Permissions": "Разрешения",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "Почтовый сервер выдаёт эту роль по умолчанию, поэтому её нельзя удалить. Сначала измените значения по умолчанию в INBUXA Admin.",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "Почтовый сервер выдаёт эту роль по умолчанию, поэтому её нельзя удалить. Сначала измените значения по умолчанию в inbuxa Admin.",
|
||||
"This role carries permissions yours doesn't.": "У этой роли есть разрешения, которых нет у вашей.",
|
||||
"Create role": "Создать роль",
|
||||
"builds on this one": "основана на этой",
|
||||
|
||||
@@ -135,8 +135,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "Показники, доступні вашій ролі, у тому вигляді, як їх повідомляє сервер.",
|
||||
"Nothing to show": "Нічого показати",
|
||||
"Could not be loaded": "Не вдалося завантажити",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "Докладні метрики, черга доставлення, журнали й налаштування сервера є в INBUXA Admin.",
|
||||
"Open INBUXA Admin": "Відкрити INBUXA Admin",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "Докладні метрики, черга доставлення, журнали й налаштування сервера є в inbuxa Admin.",
|
||||
"Open inbuxa Admin": "Відкрити inbuxa Admin",
|
||||
"Default group role": "Роль групи за замовчуванням",
|
||||
"A group needs an address.": "Групі потрібна адреса.",
|
||||
"New group": "Нова група",
|
||||
@@ -208,7 +208,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "Поштовий сервер типово надає цю роль: {kinds}. Зміна тут стосується всіх, хто отримав її так.",
|
||||
"Builds on": "Базується на",
|
||||
"Permissions": "Дозволи",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "Поштовий сервер типово надає цю роль, тому її не можна видалити. Спершу змініть типові значення в INBUXA Admin.",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "Поштовий сервер типово надає цю роль, тому її не можна видалити. Спершу змініть типові значення в inbuxa Admin.",
|
||||
"This role carries permissions yours doesn't.": "Ця роль має дозволи, яких немає у вашої.",
|
||||
"Create role": "Створити роль",
|
||||
"builds on this one": "базується на цій",
|
||||
|
||||
@@ -137,8 +137,8 @@ export const catalog: Catalog = {
|
||||
"The numbers your role can see, as the server reports them.": "您的角色可以查看的数字,按服务器报告显示。",
|
||||
"Nothing to show": "没有可显示的内容",
|
||||
"Could not be loaded": "无法加载",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.": "详细指标、投递队列、日志和服务器设置都在 INBUXA Admin 中。",
|
||||
"Open INBUXA Admin": "打开 INBUXA Admin",
|
||||
"Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.": "详细指标、投递队列、日志和服务器设置都在 inbuxa Admin 中。",
|
||||
"Open inbuxa Admin": "打开 inbuxa Admin",
|
||||
"Default group role": "默认群组角色",
|
||||
"A group needs an address.": "群组需要一个地址。",
|
||||
"New group": "新建群组",
|
||||
@@ -210,7 +210,7 @@ export const catalog: Catalog = {
|
||||
"The mail server gives this role by default to {kinds}. A change here reaches everyone who has it that way.": "邮件服务器默认将此角色授予{kinds}。在此处的更改会影响所有以此方式拥有该角色的人。",
|
||||
"Builds on": "基于",
|
||||
"Permissions": "权限",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.": "邮件服务器默认授予此角色,因此无法删除。请先在 INBUXA Admin 中更改默认设置。",
|
||||
"The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.": "邮件服务器默认授予此角色,因此无法删除。请先在 inbuxa Admin 中更改默认设置。",
|
||||
"This role carries permissions yours doesn't.": "此角色拥有您的角色所没有的权限。",
|
||||
"Create role": "创建角色",
|
||||
"builds on this one": "基于此角色",
|
||||
|
||||
@@ -108,7 +108,7 @@ export function isOccurrence(event: CalendarEvent): boolean {
|
||||
* before it is sent — rejected properties throw, inherited ones are reported to
|
||||
* the caller — rather than being posted hopefully and believed.
|
||||
*
|
||||
* [#26]: https://github.com/Coffey-Labs/ihasmail/issues/26
|
||||
* [#26]: https://git.coffeylabs.org/coffey-labs/ihasmail-github-archive/issues/26
|
||||
*/
|
||||
const OCCURRENCE_REJECTED = new Set([
|
||||
"baseEventId", "calendarIds", "isDraft", "isOrigin", "utcStart", "utcEnd",
|
||||
|
||||
@@ -26,7 +26,7 @@ import { useMail } from "./mail";
|
||||
* `ContactCard/set` down they are the same" was always claiming and is now
|
||||
* true of.
|
||||
*
|
||||
* [#173]: https://github.com/Coffey-Labs/ihasmail/issues/173
|
||||
* [#173]: https://git.coffeylabs.org/coffey-labs/ihasmail-github-archive/issues/173
|
||||
*/
|
||||
/**
|
||||
* The UIDs an address book already holds.
|
||||
|
||||
@@ -15,7 +15,7 @@ export function InbuxaWordmark({ className, height }: { className?: string; heig
|
||||
height={height}
|
||||
width={(height * 488) / 112}
|
||||
role="img"
|
||||
aria-label="INBUXA"
|
||||
aria-label="inbuxa"
|
||||
className={`notranslate ${className ?? ""}`}
|
||||
fill="currentColor"
|
||||
>
|
||||
|
||||
@@ -101,7 +101,7 @@ export interface DialogChoice {
|
||||
* which is what "Discard changes" was, on a guard whose whole purpose is to
|
||||
* stop you losing work ([#175]).
|
||||
*
|
||||
* [#175]: https://github.com/Coffey-Labs/ihasmail/issues/175
|
||||
* [#175]: https://git.coffeylabs.org/coffey-labs/ihasmail-github-archive/issues/175
|
||||
*/
|
||||
primary?: boolean;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ export function LoginPage() {
|
||||
margin-top, which a second paragraph would repeat as a gap.
|
||||
*/}
|
||||
{/* ihasmail-inbuxa: this build is INBUXA's webmail, and its site is INBUXA's. */}
|
||||
<span className="notranslate" translate="no">INBUXA webmail v{APP_VERSION}</span>
|
||||
<span className="notranslate" translate="no">inbuxa webmail v{APP_VERSION}</span>
|
||||
<br />
|
||||
<a href="https://inbuxa.org" target="_blank" rel="noopener noreferrer" className="notranslate" translate="no">inbuxa.org</a>
|
||||
{" · "}
|
||||
|
||||
@@ -126,12 +126,12 @@ export function AdminDashboard() {
|
||||
more numbers will be: this is a glance, and operating the server is
|
||||
Stalwart's own administration. The link is the operator's to give. */}
|
||||
<p className="hint admin-dashboard-note">
|
||||
{t("Detailed metrics, the delivery queue, logs and server settings are in INBUXA Admin.")}
|
||||
{t("Detailed metrics, the delivery queue, logs and server settings are in inbuxa Admin.")}
|
||||
{adminUrl && (
|
||||
<>
|
||||
{" "}
|
||||
<a href={adminUrl} target="_blank" rel="noopener noreferrer">
|
||||
{t("Open INBUXA Admin")} <ExternalLink size={13} aria-hidden="true" />
|
||||
{t("Open inbuxa Admin")} <ExternalLink size={13} aria-hidden="true" />
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -186,7 +186,7 @@ export function RoleSheet({ role, roles, defaults, entries, permissionsError, on
|
||||
{!creating && can(perms, "Role", "Destroy") && (
|
||||
<DeleteRole
|
||||
role={role}
|
||||
blocked={kinds.length ? t("The mail server gives this role by default, so it can't be deleted. Change the defaults in INBUXA Admin first.") : locked ? t("This role carries permissions yours doesn't.") : null}
|
||||
blocked={kinds.length ? t("The mail server gives this role by default, so it can't be deleted. Change the defaults in inbuxa Admin first.") : locked ? t("This role carries permissions yours doesn't.") : null}
|
||||
onDeleted={onDeleted}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -112,7 +112,7 @@ describe("the Administration dashboard", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("the pointer to INBUXA Admin", () => {
|
||||
describe("the pointer to inbuxa Admin", () => {
|
||||
let host: HTMLDivElement;
|
||||
let root: Root;
|
||||
beforeEach(() => {
|
||||
@@ -136,7 +136,7 @@ describe("the pointer to INBUXA Admin", () => {
|
||||
it("names it, and links it where the operator has said where it is", async () => {
|
||||
await renderWith("https://admin.example.com");
|
||||
const note = host.querySelector(".admin-dashboard-note")!;
|
||||
expect(note.textContent).toContain("INBUXA Admin");
|
||||
expect(note.textContent).toContain("inbuxa Admin");
|
||||
const link = note.querySelector("a")!;
|
||||
expect(link.getAttribute("href")).toBe("https://admin.example.com");
|
||||
expect(link.getAttribute("rel")).toBe("noopener noreferrer");
|
||||
@@ -144,7 +144,7 @@ describe("the pointer to INBUXA Admin", () => {
|
||||
|
||||
it("names it without a link where nobody has", async () => {
|
||||
await renderWith(null);
|
||||
expect(host.querySelector(".admin-dashboard-note")?.textContent).toContain("INBUXA Admin");
|
||||
expect(host.querySelector(".admin-dashboard-note")?.textContent).toContain("inbuxa Admin");
|
||||
expect(host.querySelector(".admin-dashboard-note a")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,13 +35,13 @@ export function AboutSettings() {
|
||||
<table className="sessions-table">
|
||||
<tbody>
|
||||
<tr><td>{t("Signed in as")}</td><td>{session?.username}</td></tr>
|
||||
<tr><td>{t("Mail server")}</td><td className="notranslate" translate="no">INBUXA</td></tr>
|
||||
<tr><td>{t("Mail server")}</td><td className="notranslate" translate="no">inbuxa</td></tr>
|
||||
<tr><td>{t("Accounts")}</td><td>{Object.values(session?.accounts ?? {}).map((a) => a.name).join(", ")}</td></tr>
|
||||
<tr><td>{t("Max upload")}</td><td>{t("{size} MB", { size: Math.round(client.maxSizeUpload / 1048576) })}</td></tr>
|
||||
<tr><td>{t("Image privacy proxy")}</td><td>{session?.ihasmail?.imageProxy ? t("enabled") : t("disabled")}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p className="hint" style={{ marginTop: 6 }}>{t("This webmail works with the INBUXA mail server, and sign-in refuses a server that doesn't offer what it needs.")}</p>
|
||||
<p className="hint" style={{ marginTop: 6 }}>{t("This webmail works with the inbuxa mail server, and sign-in refuses a server that doesn't offer what it needs.")}</p>
|
||||
<p className="hint">{tNode("{app}'s own version is the date of the commit it was built from, followed by where that commit came from: {example} was built from a commit dated the 30th of August 2026 that arrived through pull request 129. A commit that did not come through one carries its short SHA instead — {sha}. The version deliberately says nothing about the mail server; what this build needs from the server is the line above.", { example: <strong className="notranslate" translate="no">v2026.8.30+pr129</strong>, sha: <code>+g1fa6578</code> }, { app: appName })}</p>
|
||||
<h2>{t("Server capabilities")}</h2>
|
||||
<div className="row wrap gap-4">
|
||||
|
||||
Reference in New Issue
Block a user