Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec47d542dd | ||
|
|
674aef94fb |
@@ -12,6 +12,9 @@ regexes = [
|
||||
'''https?://matrix\.lotusguild\.org''',
|
||||
'''https?://code\.lotusguild\.org/api/packages/LotusGuild/npm/''',
|
||||
'''matrix\.lotusguild\.org''',
|
||||
# Lotus Chat desktop updater's minisign PUBLIC key (published in the
|
||||
# cinny-desktop README); utils/updateErrors.ts verifies Linux downloads with it.
|
||||
'''RWRZZdyii05/NUcz337A5SAbiZK\+NPVDWuiL2mM5Jk1p/LfRmNfiZ/6l''',
|
||||
]
|
||||
paths = [
|
||||
'''config\.json''',
|
||||
|
||||
@@ -108,7 +108,6 @@ import {
|
||||
TRANSLATE_TARGET_LANGUAGES,
|
||||
normalizeLang,
|
||||
isSupportedTargetLang,
|
||||
translationUnavailableText,
|
||||
} from '../../../utils/translation/langUtils';
|
||||
import { chromeTranslationEngine } from '../../../utils/translation/chromeEngine';
|
||||
import { SequenceCardStyle } from '../styles.css';
|
||||
@@ -2757,7 +2756,7 @@ function Messages() {
|
||||
description={
|
||||
translationSupported
|
||||
? 'Translate messages written in other languages into this one. Runs entirely on your device — message text never leaves your computer or touches a cloud service.'
|
||||
: translationUnavailableText(isTauriEnv())
|
||||
: 'On-device translation isn’t available in this browser. Use a Chromium desktop browser (Chrome/Edge 138+) or the Lotus desktop app.'
|
||||
}
|
||||
after={
|
||||
<SettingsSelect
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import {
|
||||
translationUnavailableText,
|
||||
normalizeLang,
|
||||
sameLanguage,
|
||||
languageName,
|
||||
@@ -54,9 +53,3 @@ test('curated list: unique codes, English present', () => {
|
||||
assert.equal(new Set(codes).size, codes.length);
|
||||
assert.ok(codes.includes('en'));
|
||||
});
|
||||
|
||||
test('translationUnavailableText: no "use the desktop app" inside the desktop app (#349)', () => {
|
||||
assert.doesNotMatch(translationUnavailableText(true), /desktop app\.$|Lotus desktop app/);
|
||||
assert.match(translationUnavailableText(true), /this version of the desktop app/);
|
||||
assert.match(translationUnavailableText(false), /this browser/);
|
||||
});
|
||||
|
||||
@@ -86,16 +86,6 @@ export function isSupportedTargetLang(code: string): boolean {
|
||||
return CURATED_NAME.has(normalizeLang(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* [Gitea #349] Why translation is unavailable, by platform. The desktop app
|
||||
* on Linux/macOS (WebKit) lacks the on-device APIs too, so it must not send
|
||||
* people to "the Lotus desktop app" they're already using.
|
||||
*/
|
||||
export const translationUnavailableText = (desktopApp: boolean): string =>
|
||||
desktopApp
|
||||
? 'On-device translation isn’t available in this version of the desktop app. It works in Chrome or Edge 138+ on a computer.'
|
||||
: 'On-device translation isn’t available in this browser. Use Chrome or Edge 138+ on a computer.';
|
||||
|
||||
/** Pure: why a manual Translate did nothing (#287). */
|
||||
export const translateSkipMessage = (from: string | undefined, targetLang: string): string =>
|
||||
from
|
||||
|
||||
@@ -69,13 +69,23 @@ test('install kinds: anything unknown keeps the in-app updater', async () => {
|
||||
test('package installs get their package manager’s command, not an Install button', async () => {
|
||||
const { packageUpdateHelp, isPackageManagedError } = await import('./updateErrors');
|
||||
const pacman = packageUpdateHelp('pacman')!;
|
||||
// Not `pacman -U <url>`: that also wants `<url>.sig`, which we don't publish.
|
||||
assert.equal(
|
||||
pacman.command,
|
||||
'curl -LO https://code.lotusguild.org/LotusGuild/cinny-desktop/releases/download/latest/LotusChat-x86_64.pkg.tar.zst && sudo pacman -U ./LotusChat-x86_64.pkg.tar.zst',
|
||||
// [cinny-desktop #36] signature, then checksum, then install, in that order;
|
||||
// a local `pacman -U ./file` (not `<url>`, which also wants `<url>.sig`).
|
||||
const steps = pacman.command!.split(' && ');
|
||||
assert.equal(steps[0], 'cd "$(mktemp -d)"');
|
||||
assert.match(
|
||||
steps[1],
|
||||
/-fLO \S+\/LotusChat-x86_64\.pkg\.tar\.zst -fLO \S+\/SHA256SUMS\.txt -fLO \S+\/SHA256SUMS\.txt\.minisig$/,
|
||||
);
|
||||
assert.equal(
|
||||
steps[2],
|
||||
'minisign -Vm SHA256SUMS.txt -P RWRZZdyii05/NUcz337A5SAbiZK+NPVDWuiL2mM5Jk1p/LfRmNfiZ/6l',
|
||||
);
|
||||
assert.equal(steps[3], 'sha256sum -c --ignore-missing SHA256SUMS.txt');
|
||||
assert.equal(steps[4], 'sudo pacman -U ./LotusChat-x86_64.pkg.tar.zst');
|
||||
assert.match(pacman.url, /LotusChat-x86_64\.pkg\.tar\.zst$/);
|
||||
const deb = packageUpdateHelp('deb')!;
|
||||
assert.match(deb.command!, /minisign -Vm SHA256SUMS\.txt/);
|
||||
assert.match(deb.command!, /sudo apt install \.\/LotusChat-x86_64\.deb$/);
|
||||
assert.equal(packageUpdateHelp('manual')?.command, undefined);
|
||||
assert.equal(packageUpdateHelp('in-app'), undefined);
|
||||
|
||||
@@ -64,23 +64,38 @@ export const toInstallKind = (value: unknown): InstallKind =>
|
||||
|
||||
export type PackageUpdateHelp = { command?: string; url: string; download: string };
|
||||
|
||||
/** The desktop updater's minisign public key (cinny-desktop tauri.conf.json). */
|
||||
export const RELEASE_MINISIGN_KEY = 'RWRZZdyii05/NUcz337A5SAbiZK+NPVDWuiL2mM5Jk1p/LfRmNfiZ/6l';
|
||||
|
||||
/**
|
||||
* [cinny-desktop #36] Download a Linux package and install it only after
|
||||
* checking the release's minisign-signed SHA256SUMS.txt. Runs in a fresh temp
|
||||
* directory so a stale SHA256SUMS.txt can't be picked up.
|
||||
*/
|
||||
const verifiedInstall = (file: string, install: string): string =>
|
||||
[
|
||||
`cd "$(mktemp -d)"`,
|
||||
`curl -fLO ${RELEASE_DOWNLOAD}/${file} -fLO ${RELEASE_DOWNLOAD}/SHA256SUMS.txt -fLO ${RELEASE_DOWNLOAD}/SHA256SUMS.txt.minisig`,
|
||||
`minisign -Vm SHA256SUMS.txt -P ${RELEASE_MINISIGN_KEY}`,
|
||||
`sha256sum -c --ignore-missing SHA256SUMS.txt`,
|
||||
`${install} ./${file}`,
|
||||
].join(' && ');
|
||||
|
||||
export const packageUpdateHelp = (kind: InstallKind): PackageUpdateHelp | undefined => {
|
||||
if (kind === 'pacman') {
|
||||
const url = `${RELEASE_DOWNLOAD}/LotusChat-x86_64.pkg.tar.zst`;
|
||||
// Download first, then install the local file: `pacman -U <url>` also
|
||||
// fetches `<url>.sig` and fails without it (we don't sign packages),
|
||||
// while a local file falls under LocalFileSigLevel (signature optional).
|
||||
// Install the local file: `pacman -U <url>` also fetches `<url>.sig` and
|
||||
// fails without it (packages aren't signed for pacman), while a local file
|
||||
// falls under LocalFileSigLevel. Integrity comes from SHA256SUMS.txt.
|
||||
return {
|
||||
command: `curl -LO ${url} && sudo pacman -U ./LotusChat-x86_64.pkg.tar.zst`,
|
||||
url,
|
||||
command: verifiedInstall('LotusChat-x86_64.pkg.tar.zst', 'sudo pacman -U'),
|
||||
url: `${RELEASE_DOWNLOAD}/LotusChat-x86_64.pkg.tar.zst`,
|
||||
download: 'Download package',
|
||||
};
|
||||
}
|
||||
if (kind === 'deb') {
|
||||
const url = `${RELEASE_DOWNLOAD}/LotusChat-x86_64.deb`;
|
||||
return {
|
||||
command: `curl -LO ${url} && sudo apt install ./LotusChat-x86_64.deb`,
|
||||
url,
|
||||
command: verifiedInstall('LotusChat-x86_64.deb', 'sudo apt install'),
|
||||
url: `${RELEASE_DOWNLOAD}/LotusChat-x86_64.deb`,
|
||||
download: 'Download package',
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user