https://github.com/diegovictor/mail-authorizer
API that uses a custom AWS Lambda as authorizer for other Lambdas. It uses a TOTP code sent to users' email to generate a JWT that allow them to get a signed URL for a given file.
https://github.com/diegovictor/mail-authorizer
authorization authorizer aws cloudfront dynamodb javascript js jwt mail-authorizer node nodejs s3 serverless serverless-framework ses totp ts typescript
Last synced: about 1 year ago
JSON representation
API that uses a custom AWS Lambda as authorizer for other Lambdas. It uses a TOTP code sent to users' email to generate a JWT that allow them to get a signed URL for a given file.
- Host: GitHub
- URL: https://github.com/diegovictor/mail-authorizer
- Owner: DiegoVictor
- License: mit
- Created: 2024-08-15T18:20:46.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-02-22T14:28:46.000Z (over 1 year ago)
- Last Synced: 2025-03-28T07:22:18.124Z (over 1 year ago)
- Topics: authorization, authorizer, aws, cloudfront, dynamodb, javascript, js, jwt, mail-authorizer, node, nodejs, s3, serverless, serverless-framework, ses, totp, ts, typescript
- Language: TypeScript
- Homepage:
- Size: 35 MB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Mail Authorizer
[](https://ci.appveyor.com/project/DiegoVictor/mail-authorizer)
[](https://aws.amazon.com/dynamodb)
[](https://www.serverless.com/)
[](https://www.typescriptlang.org/)
[](https://babeljs.io/)
[](https://jestjs.io/)
[](https://codecov.io/gh/DiegoVictor/mail-authorizer)
[](https://raw.githubusercontent.com/DiegoVictor/mail-authorizer/refs/heads/main/LICENSE)
[](http://makeapullrequest.com)
It allows users to authenticate using email address and an OTP code sent through email message and once authenticated you can download files content and upload new files. It also has a trigger for new uploaded files that adds the file to AWS DynamoDB and make it is listed in the endpoints. CloudFront was used to caching files.

## Table of Contents
* [Requirements](#requirements)
* [Install](#install)
* [.env](#env)
* [Usage](#usage)
* [Routes](#routes)
* [Requests](#requests)
* [Deploy](#deploy)
* [Running the tests](#running-the-tests)
* [Coverage report](#coverage-report)
# Requirements
* Node.js ^20.16.0
* Serveless Framework
* AWS Account
* [S3](https://aws.amazon.com/s3)
* [Lambda](https://aws.amazon.com/lambda)
* [API Gateway](https://aws.amazon.com/api-gateway)
* [DynamoDB](https://aws.amazon.com/dynamodb)
* [SES](https://aws.amazon.com/pt/ses)
* [CloudFront](https://aws.amazon.com/pt/cloudfront)
* [Secrets Manager](https://aws.amazon.com/pt/secrets-manager)
# Install
```
npm install
```
Or:
```
yarn
```
## .env
Rename the `.env.example` in the root directory to `.env` then update it with your settings.
|key|description
|---|---
|TOTP_KEY|An alphanumeric random string. Seed used to generate OTP codes. Base32 string, ie. only containing characters matching (A-Z, 2-7, =).
|JWT_SECRET|An alphanumeric random string. Used to create signed tokens.
|NOREPLY_EMAIL_ADDRESS|Email address used to send the OTP code email message.
|REGION|AWS Region.
# Usage
First you will need to generate public and private keys for CloudFront Distribution:
```shell
openssl genpkey -algorithm RSA -out private_key.pem
openssl rsa -pubout -in private_key.pem -out public_key.pem
```
> Once the files exist they will be included into the package by `serverless.ts` configuration file during deployment too.
Now we need to spin up localstack container and create the needed resources using `localstack.sh` script:
```shell
docker-compose up -d
docker-compose exec -it localstack sh -c "/var/lib/localstack/scripts/localstack.sh"
```
> Or you can access the container and run `sh /var/lib/localstack/scripts/localstack.sh`.
Now start the server:
```shell
yarn dev:server
```
Or:
```shell
npm run dev:server
```
## Routes
|route|HTTP Method|params|description|authentication
|:---|:---:|:---:|:---:|:---:
|`/files`|GET|`cursorId` query parameter.|List files.| -
|`/files/:id/signed-url`|GET|`id` of a file.|Generate a signed URL to download file content.|Required
|`/files`|POST|Body with `title` and `filename`.|Generate presigned URL to upload file.|Required
|`/auth`|POST|Body with `email`.|Send OTP code to the provided email address.| -
|`/auth`|POST|Body with `email` and `otp`.|Authenticate user and generate JWT token.| -
### Requests
* `POST /files`
Request body:
```json
{
"title": "Lorem Ipsum",
"filename": "sample.mp4"
}
```
* `POST /auth`
Request body:
```json
{
"email": "johndoe@example.com"
}
```
```json
{
"email": "johndoe@example.com",
"otp": "111065"
}
```
# Deploy
Actually you are ready to deploy:
```shell
sls deploy
```
# Running the tests
[Jest](https://jestjs.io/) was the choice to test the app, to run:
```
$ yarn test
```
Or:
```
$ npm run test
```
> Run the command in the root folder
## Coverage report
You can see the coverage report inside `tests/coverage`. They are automatically created after the tests run.