Skip to content

Commit

Permalink
feat: customize signin email
Browse files Browse the repository at this point in the history
  • Loading branch information
emiliosheinz committed May 19, 2024
1 parent 41b10bf commit d66283b
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 29 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"devDependencies": {
"@types/eslint": "^8.56.2",
"@types/node": "^20.11.20",
"@types/nodemailer": "^6.4.15",
"@types/react": "^18.2.57",
"@types/react-dom": "^18.2.19",
"@typescript-eslint/eslint-plugin": "^7.1.1",
Expand Down
98 changes: 98 additions & 0 deletions src/server/auth/EmailProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import EmailProvider from "next-auth/providers/email";
import { createTransport } from "nodemailer";
import { env } from "~/env";

export function CustomEmailProvider() {
return EmailProvider({
server: {
host: env.EMAIL_HOST,
port: Number(env.EMAIL_PORT),
auth: {
user: env.EMAIL_USER,
pass: env.EMAIL_PASSWORD,
},
secure: true,
},
from: env.EMAIL_FROM,
/**
* Sends an email with a link to the user to verify their email address.
* @see https://next-auth.js.org/providers/email#customizing-emails
* */
async sendVerificationRequest(params) {
const { identifier, url, provider } = params;
const transport = createTransport(provider.server);
const result = await transport.sendMail({
to: identifier,
from: provider.from,
subject: "Acesse sua conta SOS Pet",
text: `Acesse agora a sua conta SOS Pet e comece a ajudar animais resgatados.\n\n`,
html: html({ url }),
});
const failed = result.rejected.concat(result.pending).filter(Boolean);
if (failed.length) {
throw new Error(`Email(s) (${failed.join(", ")}) could not be sent`);
}
},
});
}

function html({ url }: { url: string }) {
const brandColor = "#333333";
const color = {
background: "#FFFFFF",
text: "#333333",
mainBackground: "#FFFFFF",
buttonBackground: brandColor,
buttonBorder: brandColor,
buttonText: "#FFFFFF",
};

return `
<body style="background: ${color.background};">
<table width="100%" border="0" cellspacing="20" cellpadding="0"
style="background: ${color.mainBackground}; max-width: 600px; margin: auto; border-radius: 10px;">
<tr>
<td align="left"
style="padding: 10px 0px; font-size: 22px; font-family: Helvetica, Arial, sans-serif; color: ${color.text};">
Acesse sua conta <strong>SOS Pet</strong>
</td>
</tr>
<tr>
<td align="center" style="padding: 20px 0;">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="left"
style="font-size: 16px; line-height: 22px; font-family: Helvetica, Arial, sans-serif; color: ${color.text};">
Olá!
<br><br>
Estamos felizes por você se juntar a nós no SOS Pet, uma comunidade dedicada a conectar animais resgatados de enchentes com abrigos disponíveis. Sua participação é essencial para garantir que esses animais encontrem um lugar seguro e acolhedor.
<br><br>
Para acessar sua conta no SOS Pet, clique no botão abaixo:
<br><br>
</td>
<tr>
<td align="center" style="border-radius: 5px;" bgcolor="${color.buttonBackground}"><a href="${url}"
target="_blank"
style="font-size: 18px; font-family: Helvetica, Arial, sans-serif; color: ${color.buttonText}; text-decoration: none; border-radius: 5px; padding: 10px 20px; border: 1px solid ${color.buttonBorder}; display: inline-block; font-weight: bold;">Acessar conta</a></td>
</tr>
<tr>
<td align="left"
style="padding: 20px 0px 0px 0px; font-size: 16px; line-height: 22px; font-family: Helvetica, Arial, sans-serif; color: ${color.text};">
Caso o botão acima não funcione, você também pode copiar e colar o link abaixo em seu navegador:
<br><br>
${url}
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="left"
style="padding: 0px 0px 10px 0px; font-size: 16px; line-height: 22px; font-family: Helvetica, Arial, sans-serif; color: ${color.text};">
Se você não solicitou este e-mail, você pode ignorá-lo com segurança.
</td>
</tr>
</table>
</body>
`;
}
9 changes: 9 additions & 0 deletions src/server/auth/GoogleProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import GoogleProvider from "next-auth/providers/google";
import { env } from "~/env";

export function CustomGoogleProvider() {
return GoogleProvider({
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
});
}
35 changes: 7 additions & 28 deletions src/server/auth.ts → src/server/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { PrismaAdapter } from "@auth/prisma-adapter";
import {
type Theme,
getServerSession,
type DefaultSession,
type NextAuthOptions,
} from "next-auth";
import { type Adapter } from "next-auth/adapters";
import GoogleProvider from "next-auth/providers/google";
import EmailProvider from "next-auth/providers/email";

import { env } from "~/env";
import { db } from "~/server/db";
import { CustomGoogleProvider } from "./GoogleProvider";
import { CustomEmailProvider } from "./EmailProvider";

/**
* Module augmentation for `next-auth` types. Allows us to add custom properties to the `session`
Expand All @@ -21,15 +20,8 @@ declare module "next-auth" {
interface Session extends DefaultSession {
user: {
id: string;
// ...other properties
// role: UserRole;
} & DefaultSession["user"];
}

// interface User {
// // ...other properties
// // role: UserRole;
// }
}

/**
Expand All @@ -41,6 +33,7 @@ export const authOptions: NextAuthOptions = {
theme: {
colorScheme: "light",
logo: "/logo-horizontal.png",
brandColor: "#333333",
},
pages: {
signIn: "/signin",
Expand All @@ -57,25 +50,11 @@ export const authOptions: NextAuthOptions = {
},
adapter: PrismaAdapter(db) as Adapter,
providers: [
GoogleProvider({
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
}),
EmailProvider({
server: {
host: env.EMAIL_HOST,
port: env.EMAIL_PORT,
auth: {
user: env.EMAIL_USER,
pass: env.EMAIL_PASSWORD,
},
secure: true,
},
from: env.EMAIL_FROM,
}),
CustomGoogleProvider(),
CustomEmailProvider(),
/**
* ...add more providers here.
*
i *
* Most other providers require a bit more work than the Discord provider. For example, the
* GitHub provider requires you to add the `refresh_token_expires_in` field to the Account
* model. Refer to the NextAuth.js docs for the provider you want to use. Example:
Expand Down
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1196,13 +1196,20 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==

"@types/node@^20.11.20":
"@types/node@*", "@types/node@^20.11.20":
version "20.12.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.12.tgz#7cbecdf902085cec634fdb362172dfe12b8f2050"
integrity sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==
dependencies:
undici-types "~5.26.4"

"@types/nodemailer@^6.4.15":
version "6.4.15"
resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.15.tgz#494be695e11c438f7f5df738fb4ab740312a6ed2"
integrity sha512-0EBJxawVNjPkng1zm2vopRctuWVCxk34JcIlRuXSf54habUWdz1FB7wHDqOqvDa8Mtpt0Q3LTXQkAs2LNyK5jQ==
dependencies:
"@types/node" "*"

"@types/normalize-package-data@^2.4.3":
version "2.4.4"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901"
Expand Down

0 comments on commit d66283b

Please sign in to comment.