Skip to content

Commit

Permalink
refactor: email disable
Browse files Browse the repository at this point in the history
  • Loading branch information
rharkor committed Sep 16, 2023
1 parent 945815d commit 5323e5f
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/components/auth/register-user-auth-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export function RegisterUserAuthForm({ dictionary, isMinimized, searchParams, ..

const registerMutation = trpc.auth.register.useMutation({
onError: (error) => {
setIsLoading(false)
const translatedError = handleMutationError(error, dictionary, router)
if (error.message.includes("email")) {
return form.setError("email", {
Expand All @@ -69,7 +70,6 @@ export function RegisterUserAuthForm({ dictionary, isMinimized, searchParams, ..
message: translatedError.message,
})
}
setIsLoading(false)
},
onSuccess: (_, vars) => {
logger.debug("Sign up successful")
Expand Down
3 changes: 2 additions & 1 deletion src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
"passwordsDoNotMatch": "Passwords do not match.",
"cannotResetAdminPasswordInDemoMode": "You cannot reset the admin password in demo mode.",
"emailNotVerified": "Please, verify your email.",
"emailAlreadyVerified": "Email verified"
"emailAlreadyVerified": "Email verified",
"emailServiceDisabled": "Email service disabled."
},
"email": "Email",
"emailPlaceholder": "[email protected]",
Expand Down
3 changes: 2 additions & 1 deletion src/langs/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
"passwordsDoNotMatch": "Les mots de passe ne correspondent pas.",
"cannotResetAdminPasswordInDemoMode": "Vous ne pouvez pas réinitialiser le mot de passe de l'administrateur en mode démo.",
"emailNotVerified": "Veuillez vérifier votre email.",
"emailAlreadyVerified": "Email vérifié"
"emailAlreadyVerified": "Email vérifié",
"emailServiceDisabled": "Le service d'email est désactivé."
},
"email": "Email",
"emailPlaceholder": "[email protected]",
Expand Down
37 changes: 21 additions & 16 deletions src/lib/api/auth/mutations.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Prisma } from "@prisma/client"
import { randomUUID } from "crypto"
import { hash } from "@/lib/bcrypt"
import { logger } from "@/lib/logger"
import { sendMail } from "@/lib/mailer"
import { prisma } from "@/lib/prisma"
import { signUpSchema } from "@/lib/schemas/auth"
Expand All @@ -24,22 +25,26 @@ export const register = async ({ input }: apiInputFromSchema<typeof signUpSchema
})

//* Send verification email
const token = randomUUID()
await prisma.userEmailVerificationToken.create({
data: {
identifier: user.id,
token: token,
expires: new Date(Date.now() + emailVerificationExpiration),
},
})
const url = `${env.VERCEL_URL ?? env.BASE_URL}/verify-email/${token}`
await sendMail({
from: `"${env.SMTP_FROM_NAME}" <${env.SMTP_FROM_EMAIL}>`,
to: email.toLowerCase(),
subject: subject,
text: plainText(url),
html: html(url),
})
if (env.ENABLE_MAILING_SERVICE === true) {
const token = randomUUID()
await prisma.userEmailVerificationToken.create({
data: {
identifier: user.id,
token: token,
expires: new Date(Date.now() + emailVerificationExpiration),
},
})
const url = `${env.VERCEL_URL ?? env.BASE_URL}/verify-email/${token}`
await sendMail({
from: `"${env.SMTP_FROM_NAME}" <${env.SMTP_FROM_EMAIL}>`,
to: email.toLowerCase(),
subject: subject,
text: plainText(url),
html: html(url),
})
} else {
logger.debug("Email verification disabled, skipping email sending on registration")
}

return { user }
} catch (error: unknown) {
Expand Down
36 changes: 21 additions & 15 deletions src/lib/api/me/email/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,27 @@ export const sendVerificationEmail = async ({ input }: apiInputFromSchema<typeof
})
}

await prisma.userEmailVerificationToken.create({
data: {
identifier: user.id,
token: token,
expires: new Date(Date.now() + emailVerificationExpiration),
},
})
const url = `${env.VERCEL_URL ?? env.BASE_URL}/verify-email/${token}`
await sendMail({
from: `"${env.SMTP_FROM_NAME}" <${env.SMTP_FROM_EMAIL}>`,
to: email.toLowerCase(),
subject: subject,
text: plainText(url),
html: html(url),
})
if (env.ENABLE_MAILING_SERVICE === true) {
await prisma.userEmailVerificationToken.create({
data: {
identifier: user.id,
token: token,
expires: new Date(Date.now() + emailVerificationExpiration),
},
})
const url = `${env.VERCEL_URL ?? env.BASE_URL}/verify-email/${token}`
await sendMail({
from: `"${env.SMTP_FROM_NAME}" <${env.SMTP_FROM_EMAIL}>`,
to: email.toLowerCase(),
subject: subject,
text: plainText(url),
html: html(url),
})
} else {
logger.debug("Email verification disabled")
if (silent) return { email }
return ApiError(throwableErrorsMessages.emailServiceDisabled, "PRECONDITION_FAILED")
}

return { email }
} catch (error: unknown) {
Expand Down
2 changes: 0 additions & 2 deletions src/lib/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,7 @@ export const nextAuthOptions: NextAuthOptions & {
async signIn({ user }) {
//* Send verification email if needed
if (user.email) {
logger.time("sendVerificationEmail")
await sendVerificationEmail({ input: { email: user.email, silent: true }, ctx: {} as ITrpcContext })
logger.timeEnd("sendVerificationEmail")
}
return true
},
Expand Down
6 changes: 5 additions & 1 deletion src/lib/mailer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import "server-only"
import { createTransport } from "nodemailer"
import { env } from "env.mjs"
import { logger } from "./logger"
import { ApiError, throwableErrorsMessages } from "./utils/server-utils"

export const configOptions = {
port: env.SMTP_PORT,
Expand All @@ -20,7 +21,10 @@ const transporter = createTransport({
})

export const sendMail = async (...params: Parameters<typeof transporter.sendMail>) => {
if (!env.ENABLE_MAILING_SERVICE) return logger.info("Email service is disabled, sending email is skipped.", params)
if (!env.ENABLE_MAILING_SERVICE) {
logger.error("Email service is disabled, sending email is skipped.")
return ApiError(throwableErrorsMessages.emailServiceDisabled, "PRECONDITION_FAILED")
}
try {
const res = await transporter.sendMail(...params)
logger.info(`Email sent to ${res.envelope.to}`)
Expand Down
3 changes: 2 additions & 1 deletion src/lib/server/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { initTRPC, TRPCError } from "@trpc/server"
import superjson from "superjson"
import { ZodError } from "zod"
import { getAuthApi } from "@/components/auth/require-auth"
import { env } from "env.mjs"
import { apiRateLimiter } from "../rate-limit"
import { Context } from "../trpc/context"
import { throwableErrorsMessages } from "../utils/server-utils"
Expand Down Expand Up @@ -57,7 +58,7 @@ const isAuthenticated = middleware(async (opts) => {
})
const hasVerifiedEmail = middleware(async (opts) => {
const { ctx } = opts
if (!ctx.session || !ctx.session.user.emailVerified) {
if (!ctx.session || (!ctx.session.user.emailVerified && env.ENABLE_MAILING_SERVICE === true)) {
throw new TRPCError({ code: "UNAUTHORIZED", message: throwableErrorsMessages.emailNotVerified })
}
return opts.next()
Expand Down

0 comments on commit 5323e5f

Please sign in to comment.