Skip to content

Commit

Permalink
Merge pull request #1 from encryptedge/dev
Browse files Browse the repository at this point in the history
feat: App Ready
  • Loading branch information
BRAVO68WEB authored Dec 29, 2023
2 parents c067b25 + 84433ef commit 30dd218
Show file tree
Hide file tree
Showing 20 changed files with 419 additions and 1,863 deletions.
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ MAIL_USER=
MAIL_PASS=
MAIL_LOGGER=
MAIL_FROM_EMAIL=
MAIL_FROM_NAME=
MAIL_FROM_NAME=
BASIC_AUTH_USERNAME=
BASIC_AUTH_PASSWORD=
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
6 changes: 6 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "@bravo68web/eslint-config",
"rules": {
"unicorn/filename-case": "off"
}
}
22 changes: 22 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Setup Node Environment
description: Prepare and install everything for nodejs repo

runs:
using: composite
steps:
- uses: pnpm/action-setup@v2

- name: Setup Node.js
uses: actions/setup-node@v3
with:
cache: pnpm
node-version: 20
registry-url: https://registry.npmjs.org/

- name: Install dependencies
shell: bash
run: pnpm i

- name: Build packages
shell: bash
run: pnpm build
22 changes: 22 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Linting

on:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]
workflow_dispatch:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Setup Environment
uses: ./.github/actions/setup

- name: Lint Code
run: pnpm lint
15 changes: 5 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
# Welcome to your CDK TypeScript project
# Mailer Lambda 📬

This is a blank project for CDK development with TypeScript.

The `cdk.json` file tells the CDK Toolkit how to execute your app.
Mailer Lambda is a simple AWS Lambda function that sends RCSCTF24 Ticket to the user's email address.

## Useful commands

* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `npx cdk deploy` deploy this stack to your default AWS account/region
* `npx cdk diff` compare deployed stack with current state
* `npx cdk synth` emits the synthesized CloudFormation template
* `pnpm build` compile typescript to js
* `pnpm watch` watch for changes and compile
* `pnpm cdk:deploy` deploy this stack to your default AWS account/region
22 changes: 6 additions & 16 deletions bin/mailer-lambda.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MailerStack } from '../lib/cdk-stack';
import * as cdk from "aws-cdk-lib";

import "source-map-support/register";

import { MailerStack } from "../lib/cdk-stack";
import { getConfig } from "../lib/config";

const config = getConfig();
const app = new cdk.App();
new MailerStack(app, 'MailerLambdaStack', {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */

/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },

/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
new MailerStack(app, "MailerLambdaStack", {
config
});
30 changes: 30 additions & 0 deletions functions/sendMail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Context } from "hono";

import sendMailWrapper from "../helpers/mailer";
import { ticketTemplate } from "../templates/ticket.template";

const sendMail = async (ctx: Context) => {
const { ticket_type, payee_name, payee_email, payee_ticket_id } = await ctx.req.json();

await sendMailWrapper({
from: process.env.MAIL_FROM,
html: ticketTemplate({
payee_name,
payee_ticket_id,
payee_email,
ticket_type
}),
to: payee_email,
replyTo: process.env.MAIL_FROM,
text: "Hope to see you at RCSCTF24!",
subject: "Your ticket for RCSCTF24 is here!",
});

return ctx.json({
message: "Email sent successfully",
});
};

export {
sendMail
};
25 changes: 25 additions & 0 deletions helpers/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { z } from "zod";

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace NodeJS {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface ProcessEnv extends z.infer<typeof envSchema> { }
}
}

const envSchema = z.object({
MAIL_HOST: z.string(),
MAIL_PORT: z.string(),
MAIL_USER: z.string(),
MAIL_PASS: z.string(),
MAIL_LOGGER: z.string(),
MAIL_FROM_EMAIL: z.string(),
MAIL_FROM_NAME: z.string(),
BASIC_AUTH_USERNAME: z.string(),
BASIC_AUTH_PASSWORD: z.string(),
});

envSchema.parse(process.env);

console.log("ENV LOADED!");
32 changes: 32 additions & 0 deletions helpers/mailer.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export interface MailConfig {
host?: string;
port?: number;
secure?: boolean;
auth?: {
user: string;
pass: string;
};
logger?: boolean;
}

type MailerConfigValues = MailConfig & Partial<ExtraMailerConfig>;

interface ExtraMailerConfig {
from_email: string;
from_name: string;
}

const ConfigValue: MailerConfigValues = {
host: process.env.MAIL_HOST,
port: Number(process.env.MAIL_PORT),
secure: false,
auth: {
user: process.env.MAIL_USER,
pass: process.env.MAIL_PASS,
},
logger: Boolean(process.env.MAIL_LOGGER),
from_email: process.env.MAIL_FROM_EMAIL,
from_name: process.env.MAIL_FROM_NAME,
};

export default ConfigValue;
18 changes: 18 additions & 0 deletions helpers/mailer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import nodemailer from "nodemailer";
import Mail from "nodemailer/lib/mailer";

import MailerConfig from "./mailer.config";

const mailConfig = MailerConfig;

const transporter = nodemailer.createTransport(mailConfig);

const sendMailWrapper = async (mail: Mail.Options): Promise<void> => {
try {
await transporter.sendMail(mail);
} catch (error) {
console.log(error);
}
};

export default sendMailWrapper;
8 changes: 0 additions & 8 deletions jest.config.js

This file was deleted.

28 changes: 23 additions & 5 deletions lambda/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
import "dotenv/config";

import { Hono } from 'hono'
import { handle } from 'hono/aws-lambda'
import { serve } from "@hono/node-server";
import { Hono } from "hono";
import { handle } from "hono/aws-lambda";
import { basicAuth } from "hono/basic-auth";

const app = new Hono()
import { sendMail } from "../functions/sendMail";

app.get('/', (c) => c.text('Hello Hono! Logger ENV => ' + process.env.MAIL_LOGGER))
const app = new Hono();

export const handler = handle(app)
app.use("/ticket/*", basicAuth({
username: process.env.BASIC_AUTH_USERNAME,
password: process.env.BASIC_AUTH_PASSWORD
}));

app.get("/", (c) => c.text("Hello Hono! Logger ENV => " + process.env.MAIL_LOGGER));
app.post("/ticket/sendMail", sendMail);

if (process.env.NODE_ENV === "development") {
serve({
fetch: app.fetch,
port: 4000,
});
}

export const handler = handle(app);
31 changes: 17 additions & 14 deletions lib/cdk-stack.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import * as cdk from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as lambda from 'aws-cdk-lib/aws-lambda'
import * as apigw from 'aws-cdk-lib/aws-apigateway'
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'
import { ConfigProps } from './config'
import * as cdk from "aws-cdk-lib";
import * as apigw from "aws-cdk-lib/aws-apigateway";
import * as lambda from "aws-cdk-lib/aws-lambda";
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
import { Construct } from "constructs";

import { ConfigProps } from "./config";

type MailerLambdaStack = cdk.StackProps & {
config: Readonly<ConfigProps>
}

export class MailerStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: MailerLambdaStack) {
super(scope, id, props)
super(scope, id, props);

const { config } = props;

const fn = new NodejsFunction(this, 'lambda', {
entry: 'lambda/index.ts',
handler: 'handler',
const fn = new NodejsFunction(this, "lambda", {
entry: "lambda/index.ts",
handler: "handler",
runtime: lambda.Runtime.NODEJS_20_X,
environment: {
MAIL_HOST: config.MAIL_HOST,
Expand All @@ -28,12 +29,14 @@ export class MailerStack extends cdk.Stack {
MAIL_FROM_EMAIL: config.MAIL_FROM_EMAIL,
MAIL_FROM_NAME: config.MAIL_FROM_NAME,
}
})
});

fn.addFunctionUrl({
authType: lambda.FunctionUrlAuthType.NONE,
})
new apigw.LambdaRestApi(this, 'mailerapi', {
});

new apigw.LambdaRestApi(this, "mailerapi", {
handler: fn,
})
});
}
}
18 changes: 11 additions & 7 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ export type ConfigProps = {
MAIL_LOGGER: string;
MAIL_FROM_EMAIL: string;
MAIL_FROM_NAME: string;
BASIC_AUTH_USERNAME: string;
BASIC_AUTH_PASSWORD: string;
};

export const getConfig = (): ConfigProps => ({
MAIL_HOST: process.env.MAIL_HOST!,
MAIL_PORT: process.env.MAIL_PORT!,
MAIL_USER: process.env.MAIL_USER!,
MAIL_PASS: process.env.MAIL_PASS!,
MAIL_LOGGER: process.env.MAIL_LOGGER!,
MAIL_FROM_EMAIL: process.env.MAIL_FROM_EMAIL!,
MAIL_FROM_NAME: process.env.MAIL_FROM_NAME!,
MAIL_HOST: process.env.MAIL_HOST,
MAIL_PORT: process.env.MAIL_PORT,
MAIL_USER: process.env.MAIL_USER,
MAIL_PASS: process.env.MAIL_PASS,
MAIL_LOGGER: process.env.MAIL_LOGGER,
MAIL_FROM_EMAIL: process.env.MAIL_FROM_EMAIL,
MAIL_FROM_NAME: process.env.MAIL_FROM_NAME,
BASIC_AUTH_USERNAME: process.env.BASIC_AUTH_USERNAME,
BASIC_AUTH_PASSWORD: process.env.BASIC_AUTH_PASSWORD,
});
Loading

0 comments on commit 30dd218

Please sign in to comment.