Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the correct website URL according to stage #7942

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
8 changes: 4 additions & 4 deletions buildSrc/DevBuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export async function runDevBuild({ stage, host, desktop, clean, ignoreMigration
u2fAppId: `${protocol}//${hostname}:${port}/u2f-appid.json`,
giftCardBaseUrl: `${protocol}//${hostname}:${port}/giftcard`,
referralBaseUrl: `${protocol}//${hostname}:${port}/signup`,
websiteBaseUrl: "https://tuta.com",
websiteBaseUrl: domainConfigs[hostname].websiteBaseUrl ?? "https://tuta.com",
},
}
}
Expand Down Expand Up @@ -223,7 +223,7 @@ globalThis.buildOptions.sqliteNativePath = "./better-sqlite3.node";`,
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const root = __dirname.split(path.sep).slice(0, -1).join(path.sep)

async function createBootstrap(env, buildDir) {
async function createBootstrap(env, buildDir, stage) {
let jsFileName
let htmlFileName
switch (env.mode) {
Expand All @@ -249,7 +249,7 @@ if (env.staticUrl == null && window.tutaoDefaultApiUrl) {
}
import('./app.js')`
await writeFile(`./${buildDir}/${jsFileName}`, template)
const html = await LaunchHtml.renderHtml(imports, env)
const html = await LaunchHtml.renderHtml(imports, env, stage)
await writeFile(`./${buildDir}/${htmlFileName}`, html)
}

Expand Down Expand Up @@ -297,6 +297,6 @@ export async function prepareAssets(stage, host, version, domainConfigs, buildDi
/** @type {EnvMode[]} */
const modes = ["Browser", "App", "Desktop"]
for (const mode of modes) {
await createBootstrap(env.create({ staticUrl: getStaticUrl(stage, mode, host), version, mode, dist: false, domainConfigs }), buildDir)
await createBootstrap(env.create({ staticUrl: getStaticUrl(stage, mode, host), version, mode, dist: false, domainConfigs }), buildDir, stage)
}
}
20 changes: 16 additions & 4 deletions buildSrc/LaunchHtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,22 @@ function getCspUrls(env) {
}
}

function getWebsiteUrl(stage) {
switch (stage) {
case "test":
return "https://test.tuta.com"
case "local":
return "https://local.tuta.com:9000"
default: // prod and host
return "https://tuta.com"
}
}

/**
* Renders the initial HTML page to bootstrap Tutanota for different environments
*/
export async function renderHtml(scripts, env) {
export async function renderHtml(scripts, env, stage) {
const websiteUrl = getWebsiteUrl(stage)
return `<!DOCTYPE html>
<html>
<head>
Expand All @@ -45,19 +57,19 @@ export async function renderHtml(scripts, env) {
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@TutaPrivacy">
<meta name="twitter:domain" content="tuta.com">
<meta name="twitter:image" content="https://tuta.com/resources/images/share-tutanota-twitter-thumbnail.png">
<meta name="twitter:image" content="${websiteUrl}/resources/images/share-tutanota-twitter-thumbnail.png">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Tuta Mail">
<meta property="og:title" content="Turn ON Privacy">
<meta property="og:description"
content="Get a free email account with quantum-safe encryption and best privacy on all your devices. Green, secure &amp; no ads!">
<meta property="og:locale" content="en">
<meta property="og:url" content="https://tuta.com/">
<meta property="og:image" content="https://tuta.com/resources/images/share-tutanota-fb-thumbnail.png">
<meta property="og:image" content="${websiteUrl}/resources/images/share-tutanota-fb-thumbnail.png">
<meta property="article:publisher" content="https://www.facebook.com/tutanota">
<meta itemprop="name" content="Turn ON Privacy">
<meta itemprop="description" content="Get a free email account with quantum-safe encryption and best privacy on all your devices. Green, secure &amp; no ads!">
<meta itemprop="image" content="https://tuta.com/images/share_image.png">
<meta itemprop="image" content="${websiteUrl}/images/share_image.png">
<meta name="apple-itunes-app" content="app-id=id922429609, affiliate-data=10lSfb">
</head>
<body style="background-color:transparent">
Expand Down
3 changes: 2 additions & 1 deletion buildSrc/buildWebapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,11 @@ self.onmessage = function (msg) {
dist: true,
domainConfigs,
}),
stage,
app,
)
if (stage !== "release") {
await createHtml(env.create({ staticUrl: restUrl, version, mode: "App", dist: true, domainConfigs }), app)
await createHtml(env.create({ staticUrl: restUrl, version, mode: "App", dist: true, domainConfigs }), stage, app)
}

await bundleServiceWorker(chunks, version, minify, buildDir)
Expand Down
5 changes: 3 additions & 2 deletions buildSrc/createHtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import path from "node:path"
* staticUrl: String defining app base url for non-production environments and the native clients.
* versionNumber: String containing the app's version number
* @param app App to be built, defaults to mail app {String}
* @param stage Deployment for which to build: 'prod' will build for the production system, 'test' for the test system, 'local' will use local.
* @returns {Promise<Awaited<void>[]>}
*/
export async function createHtml(env, app = "mail") {
export async function createHtml(env, stage, app = "mail") {
let jsFileName
let htmlFileName
const buildDir = app === "calendar" ? "build-calendar-app" : "build"
Expand Down Expand Up @@ -44,7 +45,7 @@ window.env = ${JSON.stringify(env, null, 2)}
${indexTemplate}`
return Promise.all([
_writeFile(`./${buildDir}/${jsFileName}`, index),
renderHtml(imports, env).then((content) => _writeFile(`./${buildDir}/${htmlFileName}`, content)),
renderHtml(imports, env, stage).then((content) => _writeFile(`./${buildDir}/${htmlFileName}`, content)),
])
}

Expand Down
12 changes: 6 additions & 6 deletions desktop.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ async function buildDesktopClient(version, { stage, host, platform, architecture
}

if (stage === "release") {
await createHtml(env.create({ staticUrl: tutaAppUrl, version, mode: "Desktop", dist: true, domainConfigs }))
await createHtml(env.create({ staticUrl: tutaAppUrl, version, mode: "Desktop", dist: true, domainConfigs }), stage)
await buildDesktop(desktopBaseOpts)
if (!customDesktopRelease) {
const updateUrl = new URL(tutaTestUrl)
Expand All @@ -124,7 +124,7 @@ async function buildDesktopClient(version, { stage, host, platform, architecture
// Do not notarize test build
notarize: false,
})
await createHtml(env.create({ staticUrl: tutaTestUrl, version, mode: "Desktop", dist: true, domainConfigs }))
await createHtml(env.create({ staticUrl: tutaTestUrl, version, mode: "Desktop", dist: true, domainConfigs }), stage)
await buildDesktop(desktopTestOpts)
}
} else if (stage === "local") {
Expand All @@ -140,7 +140,7 @@ async function buildDesktopClient(version, { stage, host, platform, architecture
nameSuffix: "-snapshot",
notarize: false,
})
await createHtml(env.create({ staticUrl: `http://${addr}:9000`, version, mode: "Desktop", dist: true, domainConfigs }))
await createHtml(env.create({ staticUrl: `http://${addr}:9000`, version, mode: "Desktop", dist: true, domainConfigs }), stage)
await buildDesktop(desktopLocalOpts)
} else if (stage === "test") {
const updateUrl = new URL(tutaTestUrl)
Expand All @@ -150,15 +150,15 @@ async function buildDesktopClient(version, { stage, host, platform, architecture
nameSuffix: "-test",
notarize: false,
})
await createHtml(env.create({ staticUrl: tutaTestUrl, version, mode: "Desktop", dist: true, domainConfigs }))
await createHtml(env.create({ staticUrl: tutaTestUrl, version, mode: "Desktop", dist: true, domainConfigs }), stage)
await buildDesktop(desktopTestOpts)
} else if (stage === "prod") {
const desktopProdOpts = Object.assign({}, desktopBaseOpts, {
version,
updateUrl: "http://localhost:9000/desktop",
notarize: false,
})
await createHtml(env.create({ staticUrl: tutaAppUrl, version, mode: "Desktop", dist: true, domainConfigs }))
await createHtml(env.create({ staticUrl: tutaAppUrl, version, mode: "Desktop", dist: true, domainConfigs }), stage)
await buildDesktop(desktopProdOpts)
} else {
// stage = host
Expand All @@ -168,7 +168,7 @@ async function buildDesktopClient(version, { stage, host, platform, architecture
nameSuffix: "-snapshot",
notarize: false,
})
await createHtml(env.create({ staticUrl: host, version, mode: "Desktop", dist: true, domainConfigs }))
await createHtml(env.create({ staticUrl: host, version, mode: "Desktop", dist: true, domainConfigs }), stage)
await buildDesktop(desktopHostOpts)
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/calendar-app/calendar-app.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { client } from "../common/misc/ClientDetector.js"
import m from "mithril"
import Mithril, { Children, ClassComponent, Component, RouteDefs, RouteResolver, Vnode, VnodeDOM } from "mithril"
import { lang, languageCodeToTag, languages } from "../common/misc/LanguageViewModel.js"
import { lang, languageCodeToTag, languages, setInfoLinks } from "../common/misc/LanguageViewModel.js"
import { root } from "../RootView.js"
import { disableErrorHandlingDuringLogout, handleUncaughtError } from "../common/misc/ErrorHandler.js"
import { assertMainOrNodeBoot, bootFinished, isApp, isDesktop, isOfflineStorageAvailable } from "../common/api/common/Env.js"
Expand Down Expand Up @@ -397,6 +397,8 @@ import("../mail-app/translations/en.js")
const serviceworker = await import("../common/serviceworker/ServiceWorkerClient.js")
serviceworker.init(domainConfig)

setInfoLinks(domainConfig.websiteBaseUrl)

printJobsMessage(domainConfig)
})

Expand Down
6 changes: 3 additions & 3 deletions src/common/gui/RenderLoginInfoLinks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import m, { Children } from "mithril"
import { isApp, isDesktop } from "../api/common/Env.js"
import { ExternalLink } from "./base/ExternalLink.js"
import { InfoLink, lang } from "../misc/LanguageViewModel.js"
import { InfoLinks, lang } from "../misc/LanguageViewModel.js"
import { createDropdown } from "./base/Dropdown.js"
import { mapNullable } from "@tutao/tutanota-utils"
import { getWhitelabelCustomizations } from "../misc/WhitelabelCustomizations.js"
Expand Down Expand Up @@ -48,11 +48,11 @@ export function renderInfoLinks(): Children {
}

function getImprintLink(): string | null {
return mapNullable(getWhitelabelCustomizations(window), (c) => c.imprintUrl) || InfoLink.About
return mapNullable(getWhitelabelCustomizations(window), (c) => c.imprintUrl) || InfoLinks.About
}

function getPrivacyStatementLink(): string | null {
return mapNullable(getWhitelabelCustomizations(window), (c) => c.privacyStatementUrl) || InfoLink.Privacy
return mapNullable(getWhitelabelCustomizations(window), (c) => c.privacyStatementUrl) || InfoLinks.Privacy
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/common/login/recover/TakeOverDeletedAddressDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import stream from "mithril/stream"
import { AccessBlockedError, AccessDeactivatedError, InvalidDataError, NotAuthenticatedError, TooManyRequestsError } from "../../api/common/error/RestError"
import { showProgressDialog } from "../../gui/dialogs/ProgressDialog"
import { isMailAddress } from "../../misc/FormatValidator.js"
import { InfoLink, lang } from "../../misc/LanguageViewModel.js"
import { InfoLinks, lang } from "../../misc/LanguageViewModel.js"
import { Autocomplete, TextField, TextFieldType } from "../../gui/base/TextField.js"
import { Dialog, DialogType } from "../../gui/base/Dialog"
import { HtmlEditor, HtmlEditorMode } from "../../gui/editor/HtmlEditor"
Expand All @@ -27,7 +27,7 @@ export function showTakeOverDialog(mailAddress: string, password: string): Dialo
view: () => {
return [
m(".mt", lang.get("takeOverUnusedAddress_msg")),
m(MoreInfoLink, { link: InfoLink.InactiveAccounts }),
m(MoreInfoLink, { link: InfoLinks.InactiveAccounts }),
m(TextField, {
label: "targetAddress_label",
value: targetAccountAddress(),
Expand Down
90 changes: 62 additions & 28 deletions src/common/misc/LanguageViewModel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { lazy } from "@tutao/tutanota-utils"
import { downcast, typedEntries } from "@tutao/tutanota-utils"
import { downcast, lazy, typedEntries } from "@tutao/tutanota-utils"
import type { TranslationKeyType } from "./TranslationKey"
import { getWhitelabelCustomizations, WhitelabelCustomizations } from "./WhitelabelCustomizations"
import { assertMainOrNodeBoot } from "../api/common/Env"
Expand Down Expand Up @@ -194,34 +193,69 @@ export const languageNative: ReadonlyArray<{
}
})

export const enum InfoLink {
HomePage = "https://tuta.com",
About = "https://tuta.com/imprint",
// Modifiable so `app.js` can initialize it to the website urls in the domain config
export let InfoLinks = {
HomePage: "https://tuta.com",
About: `https://tuta.com/imprint`,
//terms
Terms = "https://tuta.com/terms",
Privacy = "https://tuta.com/privacy-policy",
GiftCardsTerms = "https://tuta.com/giftCardsTerms",
Terms: `https://tuta.com/terms`,
Privacy: `https://tuta.com/privacy-policy`,
GiftCardsTerms: `https://tuta.com/giftCardsTerms`,
//faq
RecoverCode = "https://tuta.com/faq#reset",
SecondFactor = "https://tuta.com/faq#2fa",
SpamRules = "https://tuta.com/faq#spam",
DomainInfo = "https://tuta.com/faq#custom-domain",
Whitelabel = "https://tuta.com/faq#whitelabel",
ReferralLink = "https://tuta.com/faq#refer-a-friend",
Webview = "https://tuta.com/faq#webview",
Phishing = "https://tuta.com/faq#phishing",
MailAuth = "https://tuta.com/faq#mail-auth",
RunInBackground = "https://tuta.com/faq#tray-desktop",
LoadImages = "https://tuta.com/faq#load-images",
Usage = "https://tuta.com/faq#usage",
Download = "https://tuta.com/#download",
SharedMailboxes = "https://tuta.com/support/#shared-mailboxes",
InactiveAccounts = "https://tuta.com/faq/#inactive-accounts",
AppStorePaymentChange = "https://tuta.com/support/#appstore-payment-change",
AppStorePayment = "https://tuta.com/support/#appstore-payments",
AppStoreDowngrade = "https://tuta.com/support/#appstore-subscription-downgrade",
PasswordGenerator = "https://tuta.com/faq#passphrase-generator",
HomePageFreeSignup = "https://tuta.com/free-email",
RecoverCode: `https://tuta.com/faq#reset`,
SecondFactor: `https://tuta.com/faq#2fa`,
SpamRules: `https://tuta.com/faq#spam`,
DomainInfo: `https://tuta.com/faq#custom-domain`,
Whitelabel: `https://tuta.com/faq#whitelabel`,
ReferralLink: `https://tuta.com/faq#refer-a-friend`,
Webview: `https://tuta.com/faq#webview`,
Phishing: `https://tuta.com/faq#phishing`,
MailAuth: `https://tuta.com/faq#mail-auth`,
RunInBackground: `https://tuta.com/faq#tray-desktop`,
LoadImages: `https://tuta.com/faq#load-images`,
Usage: `https://tuta.com/faq#usage`,
Download: `https://tuta.com/#download`,
SharedMailboxes: `https://tuta.com/support/#shared-mailboxes`,
InactiveAccounts: `https://tuta.com/faq/#inactive-accounts`,
AppStorePaymentChange: `https://tuta.com/support/#appstore-payment-change`,
AppStorePayment: `https://tuta.com/support/#appstore-payments`,
AppStoreDowngrade: `https://tuta.com/support/#appstore-subscription-downgrade`,
PasswordGenerator: `https://tuta.com/faq#passphrase-generator`,
HomePageFreeSignup: `https://tuta.com/free-email`,
}
export type InfoLink = (typeof InfoLinks)[keyof typeof InfoLinks]

// Updates the website links in `InfoLinks` to use `websiteUrl` as the root
export function setInfoLinks(websiteUrl: string) {
InfoLinks = {
HomePage: websiteUrl,
About: `${websiteUrl}/imprint`,
//terms
Terms: `${websiteUrl}/terms`,
Privacy: `${websiteUrl}/privacy-policy`,
GiftCardsTerms: `${websiteUrl}/giftCardsTerms`,
//faq
RecoverCode: `${websiteUrl}/faq#reset`,
SecondFactor: `${websiteUrl}/faq#2fa`,
SpamRules: `${websiteUrl}/faq#spam`,
DomainInfo: `${websiteUrl}/faq#custom-domain`,
Whitelabel: `${websiteUrl}/faq#whitelabel`,
ReferralLink: `${websiteUrl}/faq#refer-a-friend`,
Webview: `${websiteUrl}/faq#webview`,
Phishing: `${websiteUrl}/faq#phishing`,
MailAuth: `${websiteUrl}/faq#mail-auth`,
RunInBackground: `${websiteUrl}/faq#tray-desktop`,
LoadImages: `${websiteUrl}/faq#load-images`,
Usage: `${websiteUrl}/faq#usage`,
Download: `${websiteUrl}/#download`,
SharedMailboxes: `${websiteUrl}/support/#shared-mailboxes`,
InactiveAccounts: `${websiteUrl}/faq/#inactive-accounts`,
AppStorePaymentChange: `${websiteUrl}/support/#appstore-payment-change`,
AppStorePayment: `${websiteUrl}/support/#appstore-payments`,
AppStoreDowngrade: `${websiteUrl}/support/#appstore-subscription-downgrade`,
PasswordGenerator: `${websiteUrl}/faq#passphrase-generator`,
HomePageFreeSignup: `${websiteUrl}/free-email`,
}
}

/**
Expand Down
12 changes: 6 additions & 6 deletions src/common/misc/news/MoreInfoLink.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { InfoLink, lang } from "../LanguageViewModel.js"
import { InfoLink, InfoLinks, lang } from "../LanguageViewModel.js"
import m, { Children, Component, Vnode } from "mithril"
import { ExternalLink, relDocument } from "../../gui/base/ExternalLink.js"

Expand All @@ -15,17 +15,17 @@ export class MoreInfoLink implements Component<MoreInfoLinkAttrs> {
view(vnode: Vnode<MoreInfoLinkAttrs>): Children {
let specialType: relDocument | undefined
switch (vnode.attrs.link) {
case InfoLink.HomePage:
case InfoLinks.HomePage:
specialType = "me"
break
case InfoLink.About:
case InfoLinks.About:
specialType = "license"
break
case InfoLink.Privacy:
case InfoLinks.Privacy:
specialType = "privacy-policy"
break
case InfoLink.Terms:
case InfoLink.GiftCardsTerms:
case InfoLinks.Terms:
case InfoLinks.GiftCardsTerms:
specialType = "terms-of-service"
break
default:
Expand Down
4 changes: 2 additions & 2 deletions src/common/misc/news/items/NewPlansNews.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NewsListItem } from "../NewsListItem.js"
import m, { Children } from "mithril"
import { NewsId } from "../../../api/entities/tutanota/TypeRefs.js"
import { InfoLink, lang } from "../../LanguageViewModel.js"
import { InfoLinks, lang } from "../../LanguageViewModel.js"
import { Button, ButtonAttrs, ButtonType } from "../../../gui/base/Button.js"
import { NewsModel } from "../NewsModel.js"
import { UserController } from "../../../api/main/UserController.js"
Expand All @@ -23,7 +23,7 @@ export class NewPlansNews implements NewsListItem {
}

render(newsId: NewsId): Children {
const lnk = InfoLink.Privacy
const lnk = InfoLinks.Privacy

const acknowledgeAction = () => {
this.newsModel.acknowledgeNews(newsId.newsItemId).then(m.redraw)
Expand Down
2 changes: 1 addition & 1 deletion src/common/misc/news/items/NewPlansOfferEndingNews.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NewsListItem } from "../NewsListItem.js"
import m, { Children } from "mithril"
import { NewsId } from "../../../api/entities/tutanota/TypeRefs.js"
import { InfoLink, lang } from "../../LanguageViewModel.js"
import { lang } from "../../LanguageViewModel.js"
import { Button, ButtonAttrs, ButtonType } from "../../../gui/base/Button.js"
import { NewsModel } from "../NewsModel.js"
import { UserController } from "../../../api/main/UserController.js"
Expand Down
Loading
Loading