Skip to content

Commit

Permalink
refactor: remove old templates
Browse files Browse the repository at this point in the history
  • Loading branch information
rharkor committed May 27, 2024
1 parent 94c3f02 commit 94f3c17
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 544 deletions.
40 changes: 35 additions & 5 deletions apps/app/src/api/auth/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ import {
verifyTotpSchema,
} from "@/api/auth/schemas"
import { emailVerificationExpiration, lastLocaleExpirationInSeconds, otpWindow, rolesAsObject } from "@/constants"
import { logoUrl } from "@/constants/medias"
import { hash } from "@/lib/bcrypt"
import { env } from "@/lib/env"
import { Locale } from "@/lib/i18n-config"
import { _getDictionary } from "@/lib/langs"
import { sendMail } from "@/lib/mailer"
import { prisma } from "@/lib/prisma"
import { redis } from "@/lib/redis"
import { html, plainText, subject } from "@/lib/templates/mail/verify-email"
import { ApiError, ensureLoggedIn, generateRandomSecret, handleApiError } from "@/lib/utils/server-utils"
import { apiInputFromSchema } from "@/types"
import VerifyEmail from "@next-boilerplate/emails/emails/verify-email"
import { logger } from "@next-boilerplate/lib"
import { Prisma } from "@prisma/client"
import { render } from "@react-email/render"

import { signUpResponseSchema } from "../me/schemas"

Expand Down Expand Up @@ -55,13 +59,39 @@ export const register = async ({ input }: apiInputFromSchema<typeof signUpSchema
expires: new Date(Date.now() + emailVerificationExpiration),
},
})
const url = `${env.VERCEL_URL ?? env.NEXT_PUBLIC_BASE_URL}/verify-email/${token}`
const verificationLink = `${env.VERCEL_URL ?? env.NEXT_PUBLIC_BASE_URL}/verify-email/${token}`
const locale = input.locale as Locale
const dictionary = await _getDictionary("transactionals", locale, {
hey: true,
verifyEmail: true,
footer: true,
thanksForSigninUpCompleteRegistration: true,
verifyYourEmailAddress: true,
verifyYourEmailAddressToCompleteYourRegistration: true,
})
const element = VerifyEmail({
verificationLink,
actionText: dictionary.verifyEmail,
contentTitle: dictionary.thanksForSigninUpCompleteRegistration,
footerText: dictionary.footer,
heyText: dictionary.hey,
logoUrl,
name: user.name ?? "",
previewText: dictionary.verifyYourEmailAddressToCompleteYourRegistration,
supportEmail: env.SUPPORT_EMAIL ?? "",
titleText: dictionary.verifyYourEmailAddress,
})
const text = render(element, {
plainText: true,
})
const html = render(element)

await sendMail({
from: `"${env.SMTP_FROM_NAME}" <${env.SMTP_FROM_EMAIL}>`,
to: email.toLowerCase(),
subject: subject,
text: plainText(url, input.locale),
html: html(url, input.locale),
subject: dictionary.verifyYourEmailAddress,
text,
html,
})
} else {
logger.debug("Email verification disabled, skipping email sending on registration")
Expand Down
41 changes: 35 additions & 6 deletions apps/app/src/api/me/email/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { z } from "zod"

import { sendVerificationEmailSchema, verifyEmailResponseSchema, verifyEmailSchema } from "@/api/me/schemas"
import { emailVerificationExpiration, resendEmailVerificationExpiration } from "@/constants"
import { logoUrl } from "@/constants/medias"
import { env } from "@/lib/env"
import { i18n } from "@/lib/i18n-config"
import { i18n, Locale } from "@/lib/i18n-config"
import { _getDictionary } from "@/lib/langs"
import { sendMail } from "@/lib/mailer"
import { prisma } from "@/lib/prisma"
import { html, plainText, subject } from "@/lib/templates/mail/verify-email"
import { ApiError, handleApiError } from "@/lib/utils/server-utils"
import { apiInputFromSchema } from "@/types"
import VerifyEmail from "@next-boilerplate/emails/emails/verify-email"
import { logger } from "@next-boilerplate/lib"
import { render } from "@react-email/render"

export const sendVerificationEmail = async ({ input }: apiInputFromSchema<typeof sendVerificationEmailSchema>) => {
try {
Expand Down Expand Up @@ -65,13 +68,39 @@ export const sendVerificationEmail = async ({ input }: apiInputFromSchema<typeof
expires: new Date(Date.now() + emailVerificationExpiration),
},
})
const url = `${env.VERCEL_URL ?? env.NEXT_PUBLIC_BASE_URL}/verify-email/${token}`
const verificationLink = `${env.VERCEL_URL ?? env.NEXT_PUBLIC_BASE_URL}/verify-email/${token}`
const locale = (user.lastLocale as Locale | null) ?? i18n.defaultLocale
const dictionary = await _getDictionary("transactionals", locale, {
hey: true,
verifyEmail: true,
footer: true,
thanksForSigninUpCompleteRegistration: true,
verifyYourEmailAddress: true,
verifyYourEmailAddressToCompleteYourRegistration: true,
})
const element = VerifyEmail({
verificationLink,
actionText: dictionary.verifyEmail,
contentTitle: dictionary.thanksForSigninUpCompleteRegistration,
footerText: dictionary.footer,
heyText: dictionary.hey,
logoUrl,
name: user.name ?? "",
previewText: dictionary.verifyYourEmailAddressToCompleteYourRegistration,
supportEmail: env.SUPPORT_EMAIL ?? "",
titleText: dictionary.verifyYourEmailAddress,
})
const text = render(element, {
plainText: true,
})
const html = render(element)

await sendMail({
from: `"${env.SMTP_FROM_NAME}" <${env.SMTP_FROM_EMAIL}>`,
to: email.toLowerCase(),
subject: subject,
text: plainText(url, user.lastLocale ?? i18n.defaultLocale),
html: html(url, user.lastLocale ?? i18n.defaultLocale),
subject: dictionary.verifyYourEmailAddress,
text,
html,
})
} else {
logger.debug("Email verification disabled")
Expand Down
46 changes: 33 additions & 13 deletions apps/app/src/api/me/password/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import { z } from "zod"

import { forgotPasswordSchema, resetPasswordResponseSchema, resetPasswordSchema } from "@/api/me/schemas"
import { resendResetPasswordExpiration, resetPasswordExpiration, rolesAsObject } from "@/constants"
import { logoUrl } from "@/constants/medias"
import { hash } from "@/lib/bcrypt"
import { env } from "@/lib/env"
import { i18n } from "@/lib/i18n-config"
import { i18n, Locale } from "@/lib/i18n-config"
import { _getDictionary } from "@/lib/langs"
import { sendMail } from "@/lib/mailer"
import { prisma } from "@/lib/prisma"
import { html, plainText, subject } from "@/lib/templates/mail/reset-password"
import { ApiError, handleApiError } from "@/lib/utils/server-utils"
import { apiInputFromSchema } from "@/types"
import ResetPasswordTemplate from "@next-boilerplate/emails/emails/reset-password"
import { logger } from "@next-boilerplate/lib"
import { render } from "@react-email/render"

export const forgotPassword = async ({ input }: apiInputFromSchema<typeof forgotPasswordSchema>) => {
try {
Expand Down Expand Up @@ -61,20 +64,37 @@ export const forgotPassword = async ({ input }: apiInputFromSchema<typeof forgot
},
})

const resetLink = `${env.VERCEL_URL ?? env.NEXT_PUBLIC_BASE_URL}/reset-password/${resetPasswordToken}`
const locale = (user.lastLocale as Locale) ?? i18n.defaultLocale
const mailDict = await _getDictionary("transactionals", locale, {
footer: true,
resetPasswordRequest: true,
resetYourPassword: true,
resetPasswordDescription: true,
hey: true,
})
const element = ResetPasswordTemplate({
footerText: mailDict.footer,
logoUrl: logoUrl,
actionText: mailDict.resetYourPassword,
contentTitle: mailDict.resetPasswordDescription,
heyText: mailDict.hey,
name: user.name ?? "",
previewText: mailDict.resetPasswordRequest,
resetLink,
supportEmail: env.SMTP_FROM_EMAIL ?? "",
titleText: mailDict.resetYourPassword,
})
const text = render(element, {
plainText: true,
})
const html = render(element)
await sendMail({
from: `"${env.SMTP_FROM_NAME}" <${env.SMTP_FROM_EMAIL}>`,
to: email,
subject: subject,
text: plainText(
user.username ?? email,
`${env.VERCEL_URL ?? env.NEXT_PUBLIC_BASE_URL}/reset-password/${resetPasswordToken}`,
user.lastLocale ?? i18n.defaultLocale
),
html: html(
user.username ?? email,
`${env.VERCEL_URL ?? env.NEXT_PUBLIC_BASE_URL}/reset-password/${resetPasswordToken}`,
user.lastLocale ?? i18n.defaultLocale
),
subject: mailDict.resetYourPassword,
text,
html,
})

return { email }
Expand Down
1 change: 1 addition & 0 deletions apps/app/src/api/me/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export const sendVerificationEmailSchema = (dictionary?: TDictionary<typeof send
emailVerified: true,
lastLocale: true,
email: true,
name: true,
}),
silent: z.boolean().optional(),
email: z.never().optional(),
Expand Down
1 change: 1 addition & 0 deletions apps/app/src/constants/medias.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const logoUrl = "https://upload.wikimedia.org/wikipedia/commons/5/5e/Vercel_logo_black.svg"
13 changes: 13 additions & 0 deletions apps/app/src/langs/transactionals/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"hey": "Hey",
"verifyYourEmailAddressToCompleteYourRegistration": "Verify your email address to complete your registration",
"verifyYourEmailAddress": "Verify your email address",
"footer": "This email was sent to you as part of our account services. If you have any questions, please contact us at",
"thanksForSigninUpCompleteRegistration": "Thanks for signing up for Animadate. To complete your registration, we just need to verify your email address.",
"verifyEmail": "Verify email",
"confirmYourNewEmail": "Confirm your new email",
"changeEmailAddressDescription": "You have requested to change your email address. Please use the following code to validate your request.",
"resetPasswordRequest": "Reset password request",
"resetYourPassword": "Reset your password",
"resetPasswordDescription": "You recently requested to reset your password for your account. Click the button below to reset it."
}
13 changes: 13 additions & 0 deletions apps/app/src/langs/transactionals/fr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"hey": "Hey",
"verifyYourEmailAddressToCompleteYourRegistration": "Vérifiez votre adresse e-mail pour compléter votre inscription",
"verifyYourEmailAddress": "Vérifiez votre adresse e-mail",
"footer": "Cet e-mail vous a été envoyé dans le cadre de nos services de compte. Si vous avez des questions, veuillez nous contacter à",
"thanksForSigninUpCompleteRegistration": "Merci de vous être inscrit à Animadate. Pour compléter votre inscription, nous devons juste vérifier votre adresse e-mail.",
"verifyEmail": "Vérifier l'e-mail",
"confirmYourNewEmail": "Confirmez votre nouvel e-mail",
"changeEmailAddressDescription": "Vous avez demandé à changer votre adresse e-mail. Veuillez utiliser le code suivant pour valider votre demande.",
"resetPasswordRequest": "Demande de réinitialisation du mot de passe",
"resetYourPassword": "Réinitialisez votre mot de passe",
"resetPasswordDescription": "Vous avez récemment demandé à réinitialiser votre mot de passe pour votre compte. Cliquez sur le bouton ci-dessous pour le réinitialiser."
}
4 changes: 4 additions & 0 deletions apps/app/src/lib/langs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ const dictionaries = {
en: () => import("../langs/errors/en.json").then((module) => module.default),
fr: () => import("../langs/errors/fr.json").then((module) => module.default),
},
transactionals: {
en: () => import("../langs/transactionals/en.json").then((module) => module.default),
fr: () => import("../langs/transactionals/fr.json").then((module) => module.default),
},
}

export type TPossibleNamespaces = keyof typeof dictionaries
Expand Down
Loading

0 comments on commit 94f3c17

Please sign in to comment.