diff --git a/INBUXA.md b/INBUXA.md index 0f143cb..5a7f215 100644 --- a/INBUXA.md +++ b/INBUXA.md @@ -20,11 +20,22 @@ keep up. Nothing here is pushed there. no address: only whether this is the person's own device, then the server's page takes it from there. With several servers, the address comes first, since its domain picks the server. +- **Branded INBUXA.** INBUXA is a product suite, and its webmail carries the + INBUXA name, mark and wordmark, so it can't be taken for public ihasmail, + which stays an independent product. The default `APP_NAME` is `INBUXA`; the + sign-in page, header, page title, installed-app name and About page say + INBUXA. ihasmail's version and AGPL source line stay as its credit. Set + `APP_NAME` to something else and that name shows as text, as in public + ihasmail. - **Tenants are offered on every server**, whatever edition it reports. `SHOW_ENTERPRISE_NOTICES` still adds the notice for an upstream Stalwart. ## Configuration +**Before any deployment, set `SOURCE_URL`** to where this fork's source is +published. The AGPL's offer has to point at the source of the code that's +running, and the default still points at public ihasmail. + Server sign-in is on when `OAUTH_CLIENT_SECRET` is set. Without it, ihasmail-inbuxa keeps public ihasmail's password form. diff --git a/server/src/config.ts b/server/src/config.ts index aeebc09..caf14e0 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -278,7 +278,7 @@ if (oauthClientSecret && !publicUrl) { export const config = { isProd, - appName: env("APP_NAME", "ihasmail"), + appName: env("APP_NAME", "INBUXA"), settingsPolicy: readSettingsPolicy(), /** * What this build calls itself: `2.16.57`. Set by the image build from diff --git a/web/index.html b/web/index.html index 0e48c8e..263b085 100644 --- a/web/index.html +++ b/web/index.html @@ -23,7 +23,7 @@ - ihasmail + INBUXA
diff --git a/web/public/img/inbuxa-mark.png b/web/public/img/inbuxa-mark.png new file mode 100644 index 0000000..86cfcf8 Binary files /dev/null and b/web/public/img/inbuxa-mark.png differ diff --git a/web/public/manifest.webmanifest b/web/public/manifest.webmanifest index 3c3d012..c16a603 100644 --- a/web/public/manifest.webmanifest +++ b/web/public/manifest.webmanifest @@ -1,7 +1,7 @@ { - "name": "ihasmail", - "short_name": "ihasmail", - "description": "Fast, friendly JMAP webmail for Stalwart", + "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", diff --git a/web/src/lib/brand.ts b/web/src/lib/brand.ts index 086a4dc..00e5c1d 100644 --- a/web/src/lib/brand.ts +++ b/web/src/lib/brand.ts @@ -10,4 +10,6 @@ * 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. */ -export const DEFAULT_APP_NAME = "ihasmail"; +// 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"; diff --git a/web/src/lib/notify/notify.ts b/web/src/lib/notify/notify.ts index 55230ea..3790578 100644 --- a/web/src/lib/notify/notify.ts +++ b/web/src/lib/notify/notify.ts @@ -1,6 +1,6 @@ import { withBase } from "../basePath"; -let baseTitle = "ihasmail"; +let baseTitle = "INBUXA"; let faviconCanvas: HTMLCanvasElement | null = null; let baseFavicon: HTMLImageElement | null = null; diff --git a/web/src/locales/de.ts b/web/src/locales/de.ts index 0856551..3fd6bff 100644 --- a/web/src/locales/de.ts +++ b/web/src/locales/de.ts @@ -1242,6 +1242,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "Filter konnten nicht gespeichert werden: {error}", "Could not send the receipt: {error}": "Die Lesebestätigung konnte nicht gesendet werden: {error}", "Could not sign in.": "Anmeldung fehlgeschlagen.", + "About INBUXA webmail": "Über INBUXA Webmail", + "Mail server": "Mailserver", "You'll enter your password on your mail server's sign-in page.": "Ihr Passwort geben Sie auf der Anmeldeseite Ihres Mailservers ein.", "You'll sign in on your mail server's own page.": "Sie melden sich auf der eigenen Seite Ihres Mailservers an.", "This sign-in didn't start in this browser. Try again.": "Diese Anmeldung wurde nicht in diesem Browser begonnen. Bitte versuchen Sie es erneut.", diff --git a/web/src/locales/es.ts b/web/src/locales/es.ts index a68a676..3e814f4 100644 --- a/web/src/locales/es.ts +++ b/web/src/locales/es.ts @@ -1215,6 +1215,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "No se pudieron guardar los filtros: {error}", "Could not send the receipt: {error}": "No se pudo enviar la confirmación de lectura: {error}", "Could not sign in.": "No se pudo iniciar sesión.", + "About INBUXA webmail": "Acerca de INBUXA webmail", + "Mail server": "Servidor de correo", "You'll enter your password on your mail server's sign-in page.": "Introducirá su contraseña en la página de inicio de sesión de su servidor de correo.", "You'll sign in on your mail server's own page.": "Iniciará sesión en la propia página de su servidor de correo.", "This sign-in didn't start in this browser. Try again.": "Este inicio de sesión no empezó en este navegador. Inténtelo de nuevo.", diff --git a/web/src/locales/fr.ts b/web/src/locales/fr.ts index 0114003..a18fbae 100644 --- a/web/src/locales/fr.ts +++ b/web/src/locales/fr.ts @@ -1220,6 +1220,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "Impossible d’enregistrer les filtres : {error}", "Could not send the receipt: {error}": "Impossible d’envoyer l’accusé de lecture : {error}", "Could not sign in.": "Connexion impossible.", + "About INBUXA webmail": "À propos d’INBUXA webmail", + "Mail server": "Serveur de messagerie", "You'll enter your password on your mail server's sign-in page.": "Vous saisirez votre mot de passe sur la page de connexion de votre serveur de messagerie.", "You'll sign in on your mail server's own page.": "Vous vous connecterez sur la page de votre serveur de messagerie.", "This sign-in didn't start in this browser. Try again.": "Cette connexion n’a pas commencé dans ce navigateur. Réessayez.", diff --git a/web/src/locales/ja.ts b/web/src/locales/ja.ts index 75d7bac..1a99e29 100644 --- a/web/src/locales/ja.ts +++ b/web/src/locales/ja.ts @@ -1223,6 +1223,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "フィルターを保存できませんでした: {error}", "Could not send the receipt: {error}": "開封確認を送信できませんでした: {error}", "Could not sign in.": "サインインできませんでした。", + "About INBUXA webmail": "INBUXA ウェブメールについて", + "Mail server": "メールサーバー", "You'll enter your password on your mail server's sign-in page.": "パスワードはメールサーバーのサインインページで入力します。", "You'll sign in on your mail server's own page.": "メールサーバー自身のページでサインインします。", "This sign-in didn't start in this browser. Try again.": "このサインインはこのブラウザーで開始されたものではありません。もう一度お試しください。", diff --git a/web/src/locales/nl.ts b/web/src/locales/nl.ts index de54627..2e54cb9 100644 --- a/web/src/locales/nl.ts +++ b/web/src/locales/nl.ts @@ -1213,6 +1213,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "Filters opslaan mislukt: {error}", "Could not send the receipt: {error}": "De leesbevestiging kon niet worden verzonden: {error}", "Could not sign in.": "Aanmelden mislukt.", + "About INBUXA webmail": "Over INBUXA webmail", + "Mail server": "Mailserver", "You'll enter your password on your mail server's sign-in page.": "U voert uw wachtwoord in op de aanmeldpagina van uw mailserver.", "You'll sign in on your mail server's own page.": "U meldt zich aan op de eigen pagina van uw mailserver.", "This sign-in didn't start in this browser. Try again.": "Deze aanmelding is niet in deze browser begonnen. Probeer het opnieuw.", diff --git a/web/src/locales/pt-BR.ts b/web/src/locales/pt-BR.ts index 911b703..39b80f4 100644 --- a/web/src/locales/pt-BR.ts +++ b/web/src/locales/pt-BR.ts @@ -1218,6 +1218,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "Não foi possível salvar os filtros: {error}", "Could not send the receipt: {error}": "Não foi possível enviar a confirmação de leitura: {error}", "Could not sign in.": "Não foi possível entrar.", + "About INBUXA webmail": "Sobre o INBUXA webmail", + "Mail server": "Servidor de e-mail", "You'll enter your password on your mail server's sign-in page.": "Você vai digitar sua senha na página de entrada do seu servidor de e-mail.", "You'll sign in on your mail server's own page.": "Você vai entrar na própria página do seu servidor de e-mail.", "This sign-in didn't start in this browser. Try again.": "Esta entrada não começou neste navegador. Tente de novo.", diff --git a/web/src/locales/ru.ts b/web/src/locales/ru.ts index 6bafd9a..0240507 100644 --- a/web/src/locales/ru.ts +++ b/web/src/locales/ru.ts @@ -1217,6 +1217,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "Не удалось сохранить фильтры: {error}", "Could not send the receipt: {error}": "Не удалось отправить уведомление о прочтении: {error}", "Could not sign in.": "Не удалось войти.", + "About INBUXA webmail": "О веб-почте INBUXA", + "Mail server": "Почтовый сервер", "You'll enter your password on your mail server's sign-in page.": "Пароль вводится на странице входа вашего почтового сервера.", "You'll sign in on your mail server's own page.": "Вход выполняется на странице вашего почтового сервера.", "This sign-in didn't start in this browser. Try again.": "Этот вход начат не в этом браузере. Попробуйте ещё раз.", diff --git a/web/src/locales/uk.ts b/web/src/locales/uk.ts index 9c87944..680faa9 100644 --- a/web/src/locales/uk.ts +++ b/web/src/locales/uk.ts @@ -1211,6 +1211,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "Не вдалося зберегти фільтри: {error}", "Could not send the receipt: {error}": "Не вдалося надіслати сповіщення про прочитання: {error}", "Could not sign in.": "Не вдалося увійти.", + "About INBUXA webmail": "Про вебпошту INBUXA", + "Mail server": "Поштовий сервер", "You'll enter your password on your mail server's sign-in page.": "Пароль вводиться на сторінці входу вашого поштового сервера.", "You'll sign in on your mail server's own page.": "Вхід виконується на сторінці вашого поштового сервера.", "This sign-in didn't start in this browser. Try again.": "Цей вхід розпочато не в цьому браузері. Спробуйте ще раз.", diff --git a/web/src/locales/zh-Hans.ts b/web/src/locales/zh-Hans.ts index b4958b1..0998f14 100644 --- a/web/src/locales/zh-Hans.ts +++ b/web/src/locales/zh-Hans.ts @@ -1222,6 +1222,8 @@ export const catalog: Catalog = { "Could not save filters: {error}": "无法保存过滤器:{error}", "Could not send the receipt: {error}": "无法发送已读回执:{error}", "Could not sign in.": "无法登录。", + "About INBUXA webmail": "关于 INBUXA 网页邮箱", + "Mail server": "邮件服务器", "You'll enter your password on your mail server's sign-in page.": "您将在邮件服务器的登录页面上输入密码。", "You'll sign in on your mail server's own page.": "您将在邮件服务器自己的页面上登录。", "This sign-in didn't start in this browser. Try again.": "此次登录不是在这个浏览器中发起的。请重试。", diff --git a/web/src/ui/InbuxaWordmark.tsx b/web/src/ui/InbuxaWordmark.tsx new file mode 100644 index 0000000..709fd51 --- /dev/null +++ b/web/src/ui/InbuxaWordmark.tsx @@ -0,0 +1,30 @@ +/** + * The INBUXA wordmark, "inbuxa" in Space Grotesk Bold, as vector paths in the + * current text color, so it reads on every palette, light or dark. The mark + * beside it is `/img/inbuxa-mark.png`: ihasmail's own cat and envelope, which + * INBUXA's logo reuses unchanged. The paths are the same ones INBUXA Admin + * draws, from the INBUXA logo bundle. + * + * ihasmail-inbuxa only. Public ihasmail keeps its own name. + */ +export function InbuxaWordmark({ className, height }: { className?: string; height: number }) { + return ( + + + + + + + + + ); +} diff --git a/web/src/views/AppShell.tsx b/web/src/views/AppShell.tsx index 2e26ed9..e0daab5 100644 --- a/web/src/views/AppShell.tsx +++ b/web/src/views/AppShell.tsx @@ -4,6 +4,7 @@ import { BookOpen, Calendar, ChevronsUpDown, FolderOpen, Globe, HelpCircle, LogO import { useSession } from "@/store/session"; import { withBase } from "@/lib/basePath"; import { DEFAULT_APP_NAME } from "@/lib/brand"; +import { InbuxaWordmark } from "@/ui/InbuxaWordmark"; import { useEffectiveTheme, useSettings } from "@/store/settings"; import { toggleTarget } from "@/lib/palette"; import { useMail } from "@/store/mail"; @@ -147,14 +148,18 @@ export function AppShell({ children }: { children: ReactNode }) { - + {/* A product name, not a word: translated it is a different product. Read from the session rather than written here, so a deployment that set APP_NAME is called what it calls itself -- the document title has taken it from there all along. */} - - {appName} - + {appName === DEFAULT_APP_NAME ? ( + + ) : ( + + {appName} + + )}
diff --git a/web/src/views/Login.tsx b/web/src/views/Login.tsx index 6a141f1..92505ee 100644 --- a/web/src/views/Login.tsx +++ b/web/src/views/Login.tsx @@ -7,6 +7,7 @@ import { DEFAULT_SOURCE_URL } from "@/lib/source"; import { APP_VERSION } from "@/lib/version"; import { DEFAULT_APP_NAME } from "@/lib/brand"; import { t } from "@/lib/i18n"; +import { InbuxaWordmark } from "@/ui/InbuxaWordmark"; export function LoginPage() { const login = useSession((s) => s.login); @@ -92,10 +93,12 @@ export function LoginPage() {
- + {/* A product name, not a word: not translated, and not guessed at - from the page it is on. */} -

{appName}

+ from the page it is on. INBUXA's is its wordmark. */} +

+ {appName === DEFAULT_APP_NAME ? : appName} +

{t("Fast, friendly webmail. Your mailbox, your way.")}

{error && ( diff --git a/web/src/views/settings/AboutSettings.tsx b/web/src/views/settings/AboutSettings.tsx index 3a120a0..59ceee9 100644 --- a/web/src/views/settings/AboutSettings.tsx +++ b/web/src/views/settings/AboutSettings.tsx @@ -4,6 +4,7 @@ import { DEFAULT_SOURCE_URL } from "@/lib/source"; import { APP_VERSION } from "@/lib/version"; import { withBase } from "@/lib/basePath"; import { t, tNode } from "@/lib/i18n"; +import { InbuxaWordmark } from "@/ui/InbuxaWordmark"; export function AboutSettings() { const session = useSession((s) => s.session); @@ -12,13 +13,16 @@ export function AboutSettings() { const sourceUrl = session?.ihasmail?.sourceUrl ?? DEFAULT_SOURCE_URL; return (
-

{t("About ihasmail")}

-

{tNode("A fast, friendly, open-source webmail for {server}, built on JMAP.", { server: {t("Stalwart Mail Server")} })}

+ {/* ihasmail-inbuxa: INBUXA's webmail, built on ihasmail, whose version + and source stay here as its credit and the AGPL's offer. */} +

{t("About INBUXA webmail")}

+

{tNode("A fast, friendly, open-source webmail for {server}, built on JMAP.", { server: INBUXA })}

- {t("ihasmail")} +
+ {/* A product name and a version string: neither is a word to translate. */} -
ihasmail v{APP_VERSION}
+
ihasmail v{APP_VERSION}
{tNode("AGPL-3.0-or-later · {source}", { source: {sourceUrl.replace(/^https?:\/\//, "")} })}
@@ -26,7 +30,7 @@ export function AboutSettings() { - + @@ -41,14 +45,3 @@ export function AboutSettings() { ); } - -/** - * Stalwart deliberately withholds its version from clients (it reports a fixed - * "1.0.0" wherever it publishes one at all), so the edition is all there is to - * show. The generation used to be reported here too, back when ihasmail spoke - * to both 0.15 and 0.16; it requires 0.16 now, so signing in at all is the - * answer to that question. - */ -function describeServer(server: { edition?: string | null } | undefined): string { - return server?.edition ? `0.16 or newer (${server.edition})` : "0.16 or newer"; -}
{t("Signed in as")}{session?.username}
{t("Stalwart")}{describeServer(session?.ihasmail?.server)}
{t("Mail server")}INBUXA
{t("Accounts")}{Object.values(session?.accounts ?? {}).map((a) => a.name).join(", ")}
{t("Max upload")}{t("{size} MB", { size: Math.round(client.maxSizeUpload / 1048576) })}
{t("Image privacy proxy")}{session?.ihasmail?.imageProxy ? t("enabled") : t("disabled")}