Skip to content

Commit

Permalink
Merge pull request #6 from coldsurfers/feature/mailer-module
Browse files Browse the repository at this point in the history
Mailer module
  • Loading branch information
yungblud authored Jan 14, 2024
2 parents 200ce6b + 2265531 commit 4479aae
Show file tree
Hide file tree
Showing 10 changed files with 649 additions and 451 deletions.
36 changes: 36 additions & 0 deletions packages/mailer-utils/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'coldsurfers', // for nodejs-typescript, or 'coldsurfers/nodejs-typescript'
],
overrides: [
{
env: {
node: true,
},
files: ['.eslintrc.{js,cjs}'],
parserOptions: {
sourceType: 'script',
},
},
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {
'react/jsx-filename-extension': 'off',
'react/jsx-props-no-spreading': 'off',
'react/prop-types': [0],
'no-bitwise': 'off',
camelcase: 'off',
'no-param-reassign': 'off',
'no-await-in-loop': 'off',
'no-return-await': 'off',
'react/no-array-index-key': 'off',
},
}
2 changes: 2 additions & 0 deletions packages/mailer-utils/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.eslintcache
dist/
6 changes: 6 additions & 0 deletions packages/mailer-utils/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"singleQuote": true
}
49 changes: 49 additions & 0 deletions packages/mailer-utils/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@coldsurfers/mailer-utils",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"source": "src/",
"files": [
"src",
"dist"
],
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.js"
}
},
"license": "MIT",
"devDependencies": {
"@types/nodemailer": "^6.4.14",
"@types/nodemailer-smtp-transport": "^2.7.8",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"eslint": "^8.56.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-coldsurfers": "^1.1.3",
"eslint-config-prettier": "^8.10.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"nodemailer": "^6.9.8",
"nodemailer-smtp-transport": "^2.7.4",
"prettier": "^2.8.1",
"typescript": "^5.3.3"
},
"scripts": {
"build": "rm -rf dist && tsc",
"prerelease": "yarn build",
"prerelease:rc": "yarn build",
"release": "release-it minor --ci",
"release:rc": "release-it --ci --preRelease=rc",
"lint": "eslint --cache \"src/**/*.{js,jsx,ts,tsx}\"",
"lint:fix": "yarn lint --fix"
},
"peerDependencies": {
"nodemailer": "^6.9.8",
"nodemailer-smtp-transport": "^2.7.4"
}
}
1 change: 1 addition & 0 deletions packages/mailer-utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './mailer-util'
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
import nconf from 'nconf'
import mailer from 'nodemailer'
import smtpTransport from 'nodemailer-smtp-transport'
import smtpTransport, { SmtpOptions } from 'nodemailer-smtp-transport'
import Mail from 'nodemailer/lib/mailer'

// eslint-disable-next-line import/prefer-default-export
export async function sendEmail({
to,
from,
text,
subject,
}: Pick<Mail.Options, 'to' | 'text' | 'subject'>) {
const transport = mailer.createTransport(
smtpTransport({
service: nconf.get('MAILER_SERVICE'),
auth: {
user: nconf.get('MAILER_EMAIL_ADDRESS'),
pass: nconf.get('secrets').MAILER_EMAIL_APP_PASSWORD,
},
})
)
smtpOptions,
}: Pick<Mail.Options, 'to' | 'text' | 'subject' | 'from'> & {
smtpOptions: SmtpOptions
}) {
const transport = mailer.createTransport(smtpTransport(smtpOptions))
const mailOptions: Mail.Options = {
from: nconf.get('MAILER_EMAIL_ADDRESS'),
from,
to,
subject, // 이메일 제목
text, // 이메일 내용
Expand Down
101 changes: 101 additions & 0 deletions packages/mailer-utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */

/* Projects */
// "incremental": true, /* Enable incremental compilation */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */

/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */

/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "resolveJsonModule": true, /* Enable importing .json files */
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */

/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */

/* Emit */
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */

/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */

/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
9 changes: 5 additions & 4 deletions packages/wamuseum-server/package.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
{
"name": "@coldsurfers/louder-server",
"name": "@coldsurfers/wamuseum-server",
"version": "1.0.0",
"private": true,
"license": "MIT",
"main": "index.js",
"scripts": {
"build": "tsc && cp -R ./src/config ./dist/config",
"db:generate": "yarn prisma format && yarn prisma generate",
"db:push": "yarn prisma db push",
"deploy": "yarn pm2 start ./src/config/ecosystem.config.js",
"dev": "NODE_ENV=development npx ts-node ./src/server.ts",
"start": "NODE_ENV=production node ./dist/server.js",
"postinstall": "yarn prisma generate",
"lint": "eslint --cache \"src/**/*.{js,jsx,ts,tsx}\"",
"lint:fix": "yarn lint --fix",
"db:generate": "yarn prisma format && yarn prisma generate",
"db:push": "yarn prisma db push"
"start": "NODE_ENV=production node ./dist/server.js"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.484.0",
"@aws-sdk/s3-presigned-post": "^3.484.0",
"@coldsurfers/mailer-utils": "1.0.0",
"@coldsurfers/shared-utils": "^1.0.1-rc.0",
"@fastify/autoload": "^5.8.0",
"@fastify/cors": "^8.5.0",
Expand Down
12 changes: 10 additions & 2 deletions packages/wamuseum-server/src/api/controllers/accounts.ctrl.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { FastifyError, RouteHandler } from 'fastify'
import { z } from 'zod'
import nconf from 'nconf'
import { sendEmail } from '@coldsurfers/mailer-utils'
import OAuth2Client from '../../lib/OAuth2Client'
import Account from '../models/Account'
import generateAuthTokenFromAccount from '../../lib/generateAuthTokenFromAccount'
import { JWTDecoded } from '../../types/jwt'
import AuthToken from '../models/AuthToken'
import Staff from '../models/Staff'
import { sendEmail } from '../../lib/mailer'
import { parseQuerystringPage } from '../../lib/parseQuerystringPage'

const mailerSubject = '[Admin Request] Admin request has been submitted'
Expand Down Expand Up @@ -70,9 +70,17 @@ export const postAccountsSignInCtrl: RouteHandler<{
}).create()
if (!newAccount) return rep.status(500).send()
sendEmail({
to: nconf.get('MAILER_EMAIL_ADDRESS'),
to: gmail,
from: nconf.get('MAILER_EMAIL_ADDRESS'),
subject: mailerSubject,
text: mailerText(gmail),
smtpOptions: {
service: nconf.get('MAILER_SERVICE'),
auth: {
user: nconf.get('MAILER_EMAIL_ADDRESS'),
pass: nconf.get('secrets').MAILER_EMAIL_APP_PASSWORD,
},
},
})
return rep.status(201).send({
account: newAccount.serialize(),
Expand Down
Loading

0 comments on commit 4479aae

Please sign in to comment.