fix(docker): use frontend url for firebase admin (@fehmer) (#6730)

fixes #6728

---------

Co-authored-by: Jack <jack@monkeytype.com>
This commit is contained in:
Christian Fehmer 2025-07-14 15:30:34 +02:00 committed by GitHub
parent c6dcfa1cb7
commit 5aec2c9a17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 50 additions and 15 deletions

View file

@ -8,7 +8,7 @@ import { MonkeyResponse } from "../../utils/monkey-response";
import * as DiscordUtils from "../../utils/discord";
import {
buildAgentLog,
isDevEnvironment,
getFrontendUrl,
replaceObjectId,
replaceObjectIds,
sanitizeString,
@ -178,11 +178,7 @@ export async function sendVerificationEmail(
const { data: link, error } = await tryCatch(
FirebaseAdmin()
.auth()
.generateEmailVerificationLink(email, {
url: isDevEnvironment()
? "http://localhost:3000"
: "https://monkeytype.com",
})
.generateEmailVerificationLink(email, { url: getFrontendUrl() })
);
if (error) {

View file

@ -28,6 +28,7 @@ const templates: Record<EmailType, EmailMetadata> = {
let transportInitialized = false;
let transporter: nodemailer.Transporter;
let emailFrom = "Monkeytype <noreply@monkeytype.com>";
export function isInitialized(): boolean {
return transportInitialized;
@ -38,7 +39,12 @@ export async function init(): Promise<void> {
return;
}
const { EMAIL_HOST, EMAIL_USER, EMAIL_PASS, EMAIL_PORT } = process.env;
const { EMAIL_HOST, EMAIL_USER, EMAIL_PASS, EMAIL_PORT, EMAIL_FROM } =
process.env;
if (EMAIL_FROM !== undefined) {
emailFrom = EMAIL_FROM;
}
if (!(EMAIL_HOST ?? "") || !(EMAIL_USER ?? "") || !(EMAIL_PASS ?? "")) {
if (isDevEnvironment()) {
@ -102,7 +108,7 @@ export async function sendEmail(
const template = await fillTemplate<typeof templateName>(templateName, data);
const mailOptions = {
from: "Monkeytype <noreply@monkeytype.com>",
from: emailFrom,
to,
subject: templates[templateName].subject,
html: template,

View file

@ -6,7 +6,7 @@ import {
setTokenCacheSize,
} from "./prometheus";
import { type DecodedIdToken, UserRecord } from "firebase-admin/auth";
import { isDevEnvironment } from "./misc";
import { getFrontendUrl } from "./misc";
import emailQueue from "../queues/email-queue";
import * as UserDAL from "../dal/user";
import { isFirebaseError } from "./error";
@ -98,11 +98,7 @@ export async function sendForgotPasswordEmail(email: string): Promise<void> {
const link = await FirebaseAdmin()
.auth()
.generatePasswordResetLink(email, {
url: isDevEnvironment()
? "http://localhost:3000"
: "https://monkeytype.com",
});
.generatePasswordResetLink(email, { url: getFrontendUrl() });
await emailQueue.sendForgotPasswordEmail(email, name, link);
} catch (err) {

View file

@ -193,6 +193,14 @@ export function isDevEnvironment(): boolean {
return process.env["MODE"] === "dev";
}
export function getFrontendUrl(): string {
return isDevEnvironment()
? "http://localhost:3000"
: process.env["FRONTEND_URL"] !== undefined
? process.env["FRONTEND_URL"]
: "https://monkeytype.com";
}
/**
* convert database object into api object
* @param data database object with `_id: ObjectId`

View file

@ -35,6 +35,11 @@ services:
- REDIS_URI=redis://monkeytype-redis:6379
- FRONTEND_URL=${MONKEYTYPE_FRONTENDURL}
- RECAPTCHA_SECRET=${RECAPTCHA_SECRET:-}
- EMAIL_HOST=${EMAIL_HOST:-}
- EMAIL_PORT=${EMAIL_PORT:-}
- EMAIL_USER=${EMAIL_USER:-}
- EMAIL_PASS=${EMAIL_PASS:-}
- EMAIL_FROM=${EMAIL_FROM:-}
volumes:
#uncomment to enable the account system, check the SELF_HOSTING.md file
#- type: bind

View file

@ -4,8 +4,8 @@ MONKEYTYPE_FRONTENDURL=http://myserver:8080
#url of the backend server, this must be accessible by your clients browser
MONKEYTYPE_BACKENDURL=http://myserver:5005
# uncomment below config if you need user accounts
# firebase config
# uncomment below config if you need user accounts
#FIREBASE_APIKEY=
#FIREBASE_AUTHDOMAIN=
#FIREBASE_PROJECTID=
@ -13,6 +13,15 @@ MONKEYTYPE_BACKENDURL=http://myserver:5005
#FIREBASE_MESSAGINGSENDERID=
#FIREBASE_APPID=
# email server config
# uncomment below if you want to send emails for e.g. password reset
#EMAIL_HOST=mail.myserver
#EMAIL_USER=mailuser
#EMAIL_PASS=mailpass
#EMAIL_PORT=465
#EMAIL_FROM="Support <noreply@myserver>"
# google recaptcha
# uncomment below config if you need user accounts
# you can use these defaults if you host this privately

View file

@ -14,6 +14,7 @@
- [Setup Firebase](#setup-firebase)
- [Update backend configuration](#update-backend-configuration)
- [Setup Recaptcha](#setup-recaptcha)
- [Setup email optional](#setup-email-optional)
- [Enable daily leaderboards](#enable-daily-leaderboards)
- [Configuration files](#configuration-files)
- [env file](#env-file)
@ -126,6 +127,20 @@ RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
RECAPTCHA_SECRET=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
```
### Setup email (optional)
To enable emails for password reset and email verification update the following config in `.env` file:
```
# email server config
# uncomment below if you want to send emails for e.g. password reset
EMAIL_HOST=mail.myserver # your mailserver domain
EMAIL_USER=mailuser # username to authenticate with your mailserver
EMAIL_PASS=mailpass # password for the user
EMAIL_PORT=465 # port, likely 465 or 578
EMAIL_FROM="Support <noreply@myserver>"
```
## Enable daily leaderboards
To enable daily leaderboards update the `backend-configuration.json` file and add/modify