├── db └── .gitkeep ├── .jetskeep ├── Rakefile ├── .ruby-version ├── .rspec ├── app ├── models │ ├── application_item.rb │ └── application_record.rb ├── helpers │ └── application_helper.rb ├── controllers │ ├── application_controller.rb │ └── emails_controller.rb └── jobs │ └── application_job.rb ├── public ├── favicon.ico ├── 500.html ├── 422.html ├── 404.html └── index.html ├── config.ru ├── .gitignore ├── config ├── environments │ ├── development.rb │ ├── test.rb │ └── production.rb ├── routes.rb ├── database.yml ├── dynamodb.yml └── application.rb ├── Procfile ├── spec ├── controllers │ └── posts_controller_spec.rb ├── spec_helper.rb └── fixtures │ └── payloads │ ├── posts-index.json │ └── posts-show.json ├── Gemfile ├── README.md └── Gemfile.lock /db/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.jetskeep: -------------------------------------------------------------------------------- 1 | pack 2 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'jets' 2 | Jets.load_tasks 3 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.5.1@serverless-ruby-simple-email 2 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /app/models/application_item.rb: -------------------------------------------------------------------------------- 1 | class ApplicationItem < Dynomite::Item 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ApplicationHelper 4 | end 5 | -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SystangoTechnologies/serverless-ruby-simple-email/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ApplicationController < Jets::Controller::Base 4 | end 5 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require "jets" 4 | Jets.boot 5 | run Jets.application 6 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < Jets::Job::Base 2 | # Adjust to increase the default timeout for all Job classes 3 | class_timeout 60 4 | end 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | .byebug_history 4 | .DS_Store 5 | .env* 6 | /node_modules 7 | /public/packs 8 | /public/packs-test 9 | bundled 10 | coverage 11 | pkg 12 | tmp 13 | .rubocop.yml 14 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | # Example: 3 | # config.function.memory_size = 1536 4 | 5 | # config.action_mailer.raise_delivery_errors = false 6 | # Docs: http://rubyonjets.com/docs/email-sending/ 7 | end 8 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | local: dynamodb-local # port 8000 2 | admin: env AWS_ACCESS_KEY_ID=$DYNAMODB_ADMIN_AWS_ACCESS_KEY_ID PORT=8001 dynamodb-admin # port 8001 3 | # web: jets server # port 8888 4 | 5 | # Using Procfile to just start local dynamodb services for now. 6 | # To start jets server for now use: 7 | # jets server 8 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | # Tell Action Mailer not to deliver emails to the real world. 3 | # The :test delivery method accumulates sent emails in the 4 | # ActionMailer::Base.deliveries array. 5 | # Docs: http://rubyonjets.com/docs/email-sending/ 6 | config.action_mailer.delivery_method = :test 7 | end 8 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | # Example: 3 | # config.function.memory_size = 2048 4 | 5 | # Ignore bad email addresses and do not raise email delivery errors. 6 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 7 | # Docs: http://rubyonjets.com/docs/email-sending/ 8 | # config.action_mailer.raise_delivery_errors = false 9 | end 10 | -------------------------------------------------------------------------------- /spec/controllers/posts_controller_spec.rb: -------------------------------------------------------------------------------- 1 | # Example: 2 | # describe PostsController, type: :controller do 3 | # it "index returns a success response" do 4 | # get '/posts' 5 | # expect(response.status).to eq 200 6 | # pp response.body 7 | # end 8 | # 9 | # it "show returns a success response" do 10 | # Post.create(id: 1) unless Post.find_by(id: 1) # TODO: set up factory_bot 11 | # get '/posts/:id', id: 1 12 | # expect(response.status).to eq 200 13 | # pp response.body 14 | # end 15 | # end 16 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Jets.application.routes.draw do 4 | root 'jets/public#show' 5 | post 'email', to: 'emails#send_email' 6 | # The jets/public#show controller can serve static utf8 content out of the public folder. 7 | # Note, as part of the deploy process Jets uploads files in the public folder to s3 8 | # and serves them out of s3 directly. S3 is well suited to serve static assets. 9 | # More info here: http://rubyonjets.com/docs/assets-serving/ 10 | any '*catchall', to: 'jets/public#show' 11 | end 12 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | gem 'aws-ses' 6 | gem 'dynomite' 7 | gem 'jets' 8 | # Include mysql2 gem if you are using ActiveRecord, remove if you are not 9 | gem 'mysql2', '~> 0.5.2' 10 | 11 | group :development, :test do 12 | gem 'byebug', platforms: %i[mri mingw x64_mingw] 13 | gem 'pry' 14 | gem 'rack' 15 | gem 'rubocop', require: false 16 | gem 'rubocop-performance' 17 | gem 'shotgun' 18 | end 19 | 20 | group :test do 21 | gem 'capybara' 22 | gem 'launchy' 23 | gem 'rspec' 24 | end 25 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["TEST"] = "1" 2 | ENV["JETS_ENV"] ||= "test" 3 | # Ensures aws api never called. Fixture home folder does not contain ~/.aws/credentails 4 | ENV['HOME'] = "spec/fixtures/home" 5 | 6 | require "byebug" 7 | require "fileutils" 8 | require "jets" 9 | 10 | abort("The Jets environment is running in production mode!") if Jets.env == "production" 11 | Jets.boot 12 | 13 | require "jets/spec_helpers" 14 | 15 | 16 | 17 | module Helpers 18 | def payload(name) 19 | JSON.load(IO.read("spec/fixtures/payloads/#{name}.json")) 20 | end 21 | end 22 | 23 | RSpec.configure do |c| 24 | c.include Helpers 25 | end 26 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: mysql2 3 | encoding: utf8 4 | pool: <%= ENV["DB_POOL"] || 5 %> 5 | database: <%= ENV['DB_NAME'] || 'serverless-ruby-simple-email-service_development' %> 6 | username: <%= ENV['DB_USER'] || 'root' %> 7 | password: <%= ENV['DB_PASS'] %> 8 | host: <%= ENV["DB_HOST"] %> 9 | url: <%= ENV['DATABASE_URL'] %> # takes higher precedence than other settings 10 | 11 | development: 12 | <<: *default 13 | database: <%= ENV['DB_NAME'] || 'serverless-ruby-simple-email-service_development' %> 14 | 15 | test: 16 | <<: *default 17 | database: serverless-ruby-simple-email-service_test 18 | 19 | production: 20 | <<: *default 21 | database: serverless-ruby-simple-email-service_production 22 | url: <%= ENV['DATABASE_URL'] %> 23 | -------------------------------------------------------------------------------- /config/dynamodb.yml: -------------------------------------------------------------------------------- 1 | # Jets::Config.project_namespace is special value results in using the project namespace. Example : 2 | # table_namespace: <%= Jets.config.project_namespace %> 3 | # This is the default value. 4 | 5 | development: 6 | table_namespace: <%= Jets.config.table_namespace %> 7 | # More examples: 8 | # table_namespace: demo-dev 9 | 10 | endpoint: http://localhost:8000 # comment out if want to test with real dynamodb 11 | # on AWS. You can also set the DYNAMODB_ENDPOINT environment variable. 12 | # You can also are actually deploying a development environment is to 13 | # change bin/server and export DYNAMODB_ENDPOINT=http://localhost:8000 at the top 14 | # there. 15 | 16 | test: 17 | # table_namespace: proj # do not include the env 18 | endpoint: http://localhost:8000 19 | table_namespace: <%= Jets.config.table_namespace %> 20 | 21 | production: 22 | table_namespace: <%= Jets.config.table_namespace %> 23 | -------------------------------------------------------------------------------- /app/controllers/emails_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class EmailsController < ApplicationController 4 | before_action :check_from 5 | before_action :check_recipients 6 | before_action :check_subject 7 | before_action :check_body 8 | before_action :initialize_ses 9 | 10 | def send_email 11 | @ses.send_email(email_configurations) 12 | render json: { message: 'Email sent!' }, status: 201 13 | rescue Aws::SES::Errors::ServiceError => e 14 | render json: { message: e }, status: 422 15 | end 16 | 17 | private 18 | 19 | def check_from 20 | return if params[:from].present? 21 | 22 | render json: { message: 'Please pass the from value' }, status: 400 23 | end 24 | 25 | def check_recipients 26 | return if params[:to].present? 27 | 28 | render json: { message: 'Please pass the recipients value' }, status: 400 29 | end 30 | 31 | def check_subject 32 | return if params[:subject].present? 33 | 34 | render json: { message: 'Please pass the subject value' }, status: 400 35 | end 36 | 37 | def check_body 38 | return if params[:textBody].present? || params[:htmlBody].present? 39 | 40 | render json: { message: 'Please pass the body value' }, status: 400 41 | end 42 | 43 | def initialize_ses 44 | @ses = AWS::SES::Base.new(region: ENV['REGION'], 45 | access_key_id: ENV['ACCESS_KEY_ID'], 46 | secret_access_key: ENV['SECRET_ACCESS_KEY']) 47 | end 48 | 49 | def email_configurations 50 | { 51 | from: params[:from], 52 | to: params[:to], 53 | cc: params[:cc], 54 | bcc: params[:bcc], 55 | subject: params[:subject], 56 | text_body: params[:textBody], 57 | html_body: params[:htmlBody] 58 | } 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /spec/fixtures/payloads/posts-index.json: -------------------------------------------------------------------------------- 1 | { 2 | "resource": "/posts", 3 | "path": "/posts", 4 | "httpMethod": "GET", 5 | "headers": { 6 | "Accept": "*/*", 7 | "CloudFront-Forwarded-Proto": "https", 8 | "CloudFront-Is-Desktop-Viewer": "true", 9 | "CloudFront-Is-Mobile-Viewer": "false", 10 | "CloudFront-Is-SmartTV-Viewer": "false", 11 | "CloudFront-Is-Tablet-Viewer": "false", 12 | "CloudFront-Viewer-Country": "US", 13 | "Host": "qg45s7uvg2.execute-api.us-east-1.amazonaws.com", 14 | "User-Agent": "curl/7.54.0", 15 | "Via": "1.1 3d3d633d266d05d90a4eea7a6a59b514.cloudfront.net (CloudFront)", 16 | "X-Amz-Cf-Id": "4mAgowukJJbA7lgTWITzgOPmdiDsXPCwy6vonS8VKPXCdEsmldVgdg==", 17 | "X-Amzn-Trace-Id": "Root=1-59fb8ea5-38c5ad176dac130f3eb9ce97", 18 | "X-Forwarded-For": "69.42.1.180, 54.239.203.118", 19 | "X-Forwarded-Port": "443", 20 | "X-Forwarded-Proto": "https" 21 | }, 22 | "queryStringParameters": null, 23 | "pathParameters": null, 24 | "stageVariables": null, 25 | "requestContext": { 26 | "path": "/prod/posts", 27 | "accountId": "123456789012", 28 | "resourceId": "ery965", 29 | "stage": "prod", 30 | "requestId": "292fbcc8-c015-11e7-94fa-cd109b693f3c", 31 | "identity": { 32 | "cognitoIdentityPoolId": null, 33 | "accountId": null, 34 | "cognitoIdentityId": null, 35 | "caller": null, 36 | "apiKey": "", 37 | "sourceIp": "69.42.1.180", 38 | "accessKey": null, 39 | "cognitoAuthenticationType": null, 40 | "cognitoAuthenticationProvider": null, 41 | "userArn": null, 42 | "userAgent": "curl/7.54.0", 43 | "user": null 44 | }, 45 | "resourcePath": "/posts", 46 | "httpMethod": "GET", 47 | "apiId": "qg45s7uvg2" 48 | }, 49 | "body": null, 50 | "isBase64Encoded": false 51 | } 52 | -------------------------------------------------------------------------------- /spec/fixtures/payloads/posts-show.json: -------------------------------------------------------------------------------- 1 | { 2 | "resource": "/posts/{id}", 3 | "path": "/posts/tung", 4 | "httpMethod": "GET", 5 | "headers": { 6 | "Accept": "*/*", 7 | "CloudFront-Forwarded-Proto": "https", 8 | "CloudFront-Is-Desktop-Viewer": "true", 9 | "CloudFront-Is-Mobile-Viewer": "false", 10 | "CloudFront-Is-SmartTV-Viewer": "false", 11 | "CloudFront-Is-Tablet-Viewer": "false", 12 | "CloudFront-Viewer-Country": "US", 13 | "Host": "qg45s7uvg2.execute-api.us-east-1.amazonaws.com", 14 | "User-Agent": "curl/7.54.0", 15 | "Via": "1.1 dc553909528b8b63475c922dc07d8ba6.cloudfront.net (CloudFront)", 16 | "X-Amz-Cf-Id": "s9NB2f_Z1scd6ksA4fcXA2r4QhpSKQ6QcTLQHGfxDPfI-X7sXM3YLg==", 17 | "X-Amzn-Trace-Id": "Root=1-59fb8ecb-586ab81d73e36910793d767c", 18 | "X-Forwarded-For": "69.42.1.180, 54.239.203.97", 19 | "X-Forwarded-Port": "443", 20 | "X-Forwarded-Proto": "https" 21 | }, 22 | "queryStringParameters": null, 23 | "pathParameters": { 24 | "id": "tung" 25 | }, 26 | "stageVariables": null, 27 | "requestContext": { 28 | "path": "/prod/posts/tung", 29 | "accountId": "123456789012", 30 | "resourceId": "wf2gvu", 31 | "stage": "prod", 32 | "requestId": "3feafb4e-c015-11e7-85c9-194f38f4c414", 33 | "identity": { 34 | "cognitoIdentityPoolId": null, 35 | "accountId": null, 36 | "cognitoIdentityId": null, 37 | "caller": null, 38 | "apiKey": "", 39 | "sourceIp": "69.42.1.180", 40 | "accessKey": null, 41 | "cognitoAuthenticationType": null, 42 | "cognitoAuthenticationProvider": null, 43 | "userArn": null, 44 | "userAgent": "curl/7.54.0", 45 | "user": null 46 | }, 47 | "resourcePath": "/posts/{id}", 48 | "httpMethod": "GET", 49 | "apiId": "qg45s7uvg2" 50 | }, 51 | "body": null, 52 | "isBase64Encoded": false 53 | } 54 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Ruby on Jets 5 | 6 | 7 | 63 | 64 | 65 | 66 |
67 |
68 | 69 |

Welcome and congrats!
Jets is running.

70 |
71 |
72 |

73 | To get started: 74 |

75 |

76 |         $ jets generate scaffold Post title:string
77 |         $ jets db:create db:migrate
78 |         $ jets server
79 |         $ open http://localhost:8888/posts
80 |         $ jets help
81 |       
82 |

More on info: rubyonjets.com

83 |

Also check out the Jets CLI reference.

84 |
85 |

86 | Jets version: 1.8.9
87 | Ruby version: 2.5.3 88 |

89 |
90 | 91 | 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serverless Email Service 2 | This is a simple serverless application build over Jets framework of the ruby. The application illustrates how we can create a simple serverless email service using jets framework. 3 | ## Requirements 4 | * RVM 5 | * Ruby(2.5.1) 6 | * AWS CLI 7 | 8 | ## Setup 9 | 10 | ### Step 1 - Install RVM 11 | * Follow the steps given here: https://rvm.io/rvm/install, to install RVM in your machines 12 | 13 | ### Step 2 - Install Ruby 14 | To install ruby(2.5.1) in your machine, run following command 15 | ```sh 16 | $ rvm install ruby-2.5.1 17 | ``` 18 | ### Step 3 - Install & Configure AWS 19 | ```sh 20 | $ sudo apt install awscli 21 | $ aws configure 22 | ``` 23 | ### Step 4 - Take clone of the repository 24 | 25 | ```ruby_on_rails 26 | $ git clone https://github.com/SystangoTechnologies/serverless-ruby-simple-email.git 27 | $ cd serverless-ruby-simple-email 28 | $ bundle install 29 | ``` 30 | ### Step 5 - Run Application 31 | 32 | To start your the jets server locally, you need to run 33 | 34 | ```ruby_on_rails 35 | $ jets s 36 | ``` 37 | It will start your service on http://localhost:8888. 38 | 39 | To send email, you can hit the following endpoint as a POST request. 40 | 41 | ```ruby_on_rails 42 | $ curl -X POST \ 43 | http://localhost:8888/send_email \ 44 | -H 'Authorization: {YOUR AUTHORIZATION KEY}' \ 45 | -H 'Content-Type: application/x-www-form-urlencoded' \ 46 | -H 'cache-control: no-cache' 47 | -d '{"sender": "sender@domain.com", "recipients": ["recipient1@domain.com", "recipient2@domain.com"],"subject": "Test email", "body": "

Hi User!

"}' 48 | ``` 49 | The required parameters in the request are: 50 | * **sender** [string]: Email address of sender 51 | * **recipients** [array]: Array of recipients emails. 52 | * **subject** [string]: Subject of Email 53 | * **body** [string]: Body of subject(HTML or normal text) 54 | 55 | ## Deployment 56 | To deploy your application to AWS, you need to just run single command 57 | 58 | ```ruby_on_rails 59 | $ jets deploy 60 | ``` 61 | 62 | Once the application is deployed you will get the API endpoint using which you can access Live API. 63 | 64 | ## Security 65 | 66 | Once API gateway is created, you must setup Usage plan along with their API Keys form API gateway console. For this, you can follow the [official doc](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-setup-api-key-with-console.html) for the same given by AWS. 67 | 68 | If you want a custom authorization instead of this, just comment out the **before_filter:authorize** line in application.rb to make custom authorization work. 69 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | config.project_name = 'serverless-ruby-simple-email' 3 | config.mode = 'api' 4 | 5 | config.prewarm.enable = true # default is true 6 | # config.prewarm.rate = '30 minutes' # default is '30 minutes' 7 | # config.prewarm.concurrency = 2 # default is 2 8 | # config.prewarm.public_ratio = 3 # default is 3 9 | 10 | # config.env_extra = 2 # can also set this with JETS_ENV_EXTRA 11 | # config.extra_autoload_paths = [] 12 | 13 | # config.asset_base_url = 'https://cloudfront.domain.com/assets' # example 14 | 15 | config.cors = true # for '*'' # defaults to false 16 | config.cors_preflight = { 17 | "access-control-allow-methods" => "DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT", 18 | "access-control-allow-headers" => "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent", 19 | } 20 | # config.cors = '*.mydomain.com' # for specific domain 21 | 22 | # config.function.timeout = 30 # defaults to 30 23 | # config.function.role = "arn:aws:iam::#{Jets.aws.account}:role/service-role/pre-created" 24 | # config.function.memory_size = 1536 25 | 26 | # config.api.endpoint_type = 'PRIVATE' # Default is 'EDGE' (https://docs.aws.amazon.com/apigateway/api-reference/link-relation/restapi-create/#endpointConfiguration) 27 | 28 | # config.function.environment = { 29 | # global_app_key1: "global_app_value1", 30 | # global_app_key2: "global_app_value2", 31 | # } 32 | # More examples: 33 | # config.function.dead_letter_queue = { target_arn: "arn" } 34 | # config.function.vpc_config = { 35 | # security_group_ids: [ "sg-1", "sg-2" ], 36 | # subnet_ids: [ "subnet-1", "subnet-2" ] 37 | # } 38 | # The config.function settings to the CloudFormation Lambda Function properties. 39 | # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html 40 | # Underscored format can be used for keys to make it look more ruby-ish. 41 | 42 | # Assets settings 43 | # The config.assets.folders are folders within the public folder that will be set 44 | # to public-read on s3 and served directly. IE: public/assets public/images public/packs 45 | # config.assets.folders = %w[assets images packs] 46 | # config.assets.max_age = 3600 # when to expire assets 47 | # config.assets.cache_control = nil # IE: "public, max-age=3600" # override max_age for more fine-grain control. 48 | # config.assets.base_url = nil # IE: https://cloudfront.com/my/base/path, defaults to the s3 bucket url 49 | # IE: https://s3-us-west-2.amazonaws.com/demo-dev-s3bucket-1inlzkvujq8zb 50 | 51 | # config.api.endpoint_type = 'PRIVATE' # Default is 'EDGE' https://amzn.to/2r0Iu2L 52 | # config.api.authorization_type = "AWS_IAM" # default is 'NONE' https://amzn.to/2qZ7zLh 53 | 54 | 55 | # config.domain.hosted_zone_name = "example.com" 56 | # us-west-2 REGIONAL endpoint 57 | # config.domain.cert_arn = "arn:aws:acm:us-west-2:112233445566:certificate/8d8919ce-a710-4050-976b-b33da991e123" 58 | # us-east-1 EDGE endpoint 59 | # config.domain.cert_arn = "arn:aws:acm:us-east-1:112233445566:certificate/d68472ba-04f8-45ba-b9db-14f839d57123" 60 | # config.domain.endpoint_type = "EDGE" 61 | 62 | # By default logger needs to log to $stderr for CloudWatch to receive Lambda messages, but for 63 | # local testing environment you may want to log these messages to 'test.log' file to keep your 64 | # testing suite output readable. 65 | # config.logger = Jets::Logger.new($strerr) 66 | end 67 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (6.0.2.1) 5 | actionpack (= 6.0.2.1) 6 | actionview (= 6.0.2.1) 7 | activejob (= 6.0.2.1) 8 | mail (~> 2.5, >= 2.5.4) 9 | rails-dom-testing (~> 2.0) 10 | actionpack (6.0.2.1) 11 | actionview (= 6.0.2.1) 12 | activesupport (= 6.0.2.1) 13 | rack (~> 2.0, >= 2.0.8) 14 | rack-test (>= 0.6.3) 15 | rails-dom-testing (~> 2.0) 16 | rails-html-sanitizer (~> 1.0, >= 1.2.0) 17 | actionview (6.0.2.1) 18 | activesupport (= 6.0.2.1) 19 | builder (~> 3.1) 20 | erubi (~> 1.4) 21 | rails-dom-testing (~> 2.0) 22 | rails-html-sanitizer (~> 1.1, >= 1.2.0) 23 | activejob (6.0.2.1) 24 | activesupport (= 6.0.2.1) 25 | globalid (>= 0.3.6) 26 | activemodel (6.0.2.1) 27 | activesupport (= 6.0.2.1) 28 | activerecord (6.0.2.1) 29 | activemodel (= 6.0.2.1) 30 | activesupport (= 6.0.2.1) 31 | activesupport (6.0.2.1) 32 | concurrent-ruby (~> 1.0, >= 1.0.2) 33 | i18n (>= 0.7, < 2) 34 | minitest (~> 5.1) 35 | tzinfo (~> 1.1) 36 | zeitwerk (~> 2.2) 37 | addressable (2.7.0) 38 | public_suffix (>= 2.0.2, < 5.0) 39 | ast (2.4.0) 40 | aws-eventstream (1.0.3) 41 | aws-mfa-secure (0.4.0) 42 | activesupport 43 | aws-sdk-core 44 | aws_config 45 | memoist 46 | rainbow 47 | thor 48 | zeitwerk 49 | aws-partitions (1.262.0) 50 | aws-sdk-apigateway (1.36.0) 51 | aws-sdk-core (~> 3, >= 3.71.0) 52 | aws-sigv4 (~> 1.1) 53 | aws-sdk-cloudformation (1.29.0) 54 | aws-sdk-core (~> 3, >= 3.71.0) 55 | aws-sigv4 (~> 1.1) 56 | aws-sdk-cloudwatchlogs (1.27.0) 57 | aws-sdk-core (~> 3, >= 3.71.0) 58 | aws-sigv4 (~> 1.1) 59 | aws-sdk-core (3.86.0) 60 | aws-eventstream (~> 1.0, >= 1.0.2) 61 | aws-partitions (~> 1, >= 1.239.0) 62 | aws-sigv4 (~> 1.1) 63 | jmespath (~> 1.0) 64 | aws-sdk-dynamodb (1.41.0) 65 | aws-sdk-core (~> 3, >= 3.71.0) 66 | aws-sigv4 (~> 1.1) 67 | aws-sdk-kinesis (1.20.0) 68 | aws-sdk-core (~> 3, >= 3.71.0) 69 | aws-sigv4 (~> 1.1) 70 | aws-sdk-kms (1.27.0) 71 | aws-sdk-core (~> 3, >= 3.71.0) 72 | aws-sigv4 (~> 1.1) 73 | aws-sdk-lambda (1.34.0) 74 | aws-sdk-core (~> 3, >= 3.71.0) 75 | aws-sigv4 (~> 1.1) 76 | aws-sdk-s3 (1.60.1) 77 | aws-sdk-core (~> 3, >= 3.83.0) 78 | aws-sdk-kms (~> 1) 79 | aws-sigv4 (~> 1.1) 80 | aws-sdk-sns (1.21.0) 81 | aws-sdk-core (~> 3, >= 3.71.0) 82 | aws-sigv4 (~> 1.1) 83 | aws-sdk-sqs (1.23.1) 84 | aws-sdk-core (~> 3, >= 3.71.0) 85 | aws-sigv4 (~> 1.1) 86 | aws-sdk-ssm (1.69.0) 87 | aws-sdk-core (~> 3, >= 3.71.0) 88 | aws-sigv4 (~> 1.1) 89 | aws-ses (0.6.0) 90 | builder 91 | mail (> 2.2.5) 92 | mime-types 93 | xml-simple 94 | aws-sigv4 (1.1.0) 95 | aws-eventstream (~> 1.0, >= 1.0.2) 96 | aws_config (0.1.0) 97 | builder (3.2.4) 98 | byebug (11.0.1) 99 | capybara (3.30.0) 100 | addressable 101 | mini_mime (>= 0.1.3) 102 | nokogiri (~> 1.8) 103 | rack (>= 1.6.0) 104 | rack-test (>= 0.6.3) 105 | regexp_parser (~> 1.5) 106 | xpath (~> 3.2) 107 | cfn_camelizer (0.4.9) 108 | activesupport 109 | memoist 110 | rainbow 111 | cfnresponse (0.4.0) 112 | coderay (1.1.2) 113 | concurrent-ruby (1.1.5) 114 | crass (1.0.5) 115 | diff-lcs (1.3) 116 | dotenv (2.7.5) 117 | dynomite (1.2.5) 118 | activesupport 119 | aws-sdk-dynamodb 120 | rainbow 121 | erubi (1.9.0) 122 | gems (1.2.0) 123 | globalid (0.4.2) 124 | activesupport (>= 4.2.0) 125 | hashie (4.0.0) 126 | i18n (1.7.1) 127 | concurrent-ruby (~> 1.0) 128 | jaro_winkler (1.5.4) 129 | jets (2.3.11) 130 | actionmailer (~> 6.0.0) 131 | actionpack (~> 6.0.0) 132 | actionview (~> 6.0.0) 133 | activerecord (~> 6.0.0) 134 | activesupport (~> 6.0.0) 135 | aws-mfa-secure (~> 0.4.0) 136 | aws-sdk-apigateway 137 | aws-sdk-cloudformation 138 | aws-sdk-cloudwatchlogs 139 | aws-sdk-dynamodb 140 | aws-sdk-kinesis 141 | aws-sdk-lambda 142 | aws-sdk-s3 143 | aws-sdk-sns 144 | aws-sdk-sqs 145 | aws-sdk-ssm 146 | cfn_camelizer (~> 0.4.6) 147 | cfnresponse 148 | dotenv 149 | gems 150 | hashie 151 | jets-gems 152 | jets-html-sanitizer 153 | json 154 | kramdown 155 | memoist 156 | mimemagic 157 | rack 158 | railties (~> 6.0.0) 159 | rainbow 160 | recursive-open-struct 161 | shotgun 162 | text-table 163 | thor 164 | zeitwerk 165 | jets-gems (0.2.0) 166 | gems 167 | jets-html-sanitizer (1.0.4) 168 | loofah (~> 2.2, >= 2.2.2) 169 | jmespath (1.4.0) 170 | json (2.3.0) 171 | kramdown (2.1.0) 172 | launchy (2.4.3) 173 | addressable (~> 2.3) 174 | loofah (2.4.0) 175 | crass (~> 1.0.2) 176 | nokogiri (>= 1.5.9) 177 | mail (2.7.1) 178 | mini_mime (>= 0.1.1) 179 | memoist (0.16.2) 180 | method_source (0.9.2) 181 | mime-types (3.3.1) 182 | mime-types-data (~> 3.2015) 183 | mime-types-data (3.2019.1009) 184 | mimemagic (0.3.3) 185 | mini_mime (1.0.2) 186 | mini_portile2 (2.4.0) 187 | minitest (5.13.0) 188 | mysql2 (0.5.3) 189 | nokogiri (1.10.7) 190 | mini_portile2 (~> 2.4.0) 191 | parallel (1.19.1) 192 | parser (2.7.0.1) 193 | ast (~> 2.4.0) 194 | pry (0.12.2) 195 | coderay (~> 1.1.0) 196 | method_source (~> 0.9.0) 197 | public_suffix (4.0.3) 198 | rack (2.0.8) 199 | rack-test (1.1.0) 200 | rack (>= 1.0, < 3) 201 | rails-dom-testing (2.0.3) 202 | activesupport (>= 4.2.0) 203 | nokogiri (>= 1.6) 204 | rails-html-sanitizer (1.3.0) 205 | loofah (~> 2.3) 206 | railties (6.0.2.1) 207 | actionpack (= 6.0.2.1) 208 | activesupport (= 6.0.2.1) 209 | method_source 210 | rake (>= 0.8.7) 211 | thor (>= 0.20.3, < 2.0) 212 | rainbow (3.0.0) 213 | rake (13.0.1) 214 | recursive-open-struct (1.1.0) 215 | regexp_parser (1.6.0) 216 | rspec (3.9.0) 217 | rspec-core (~> 3.9.0) 218 | rspec-expectations (~> 3.9.0) 219 | rspec-mocks (~> 3.9.0) 220 | rspec-core (3.9.1) 221 | rspec-support (~> 3.9.1) 222 | rspec-expectations (3.9.0) 223 | diff-lcs (>= 1.2.0, < 2.0) 224 | rspec-support (~> 3.9.0) 225 | rspec-mocks (3.9.1) 226 | diff-lcs (>= 1.2.0, < 2.0) 227 | rspec-support (~> 3.9.0) 228 | rspec-support (3.9.2) 229 | rubocop (0.79.0) 230 | jaro_winkler (~> 1.5.1) 231 | parallel (~> 1.10) 232 | parser (>= 2.7.0.1) 233 | rainbow (>= 2.2.2, < 4.0) 234 | ruby-progressbar (~> 1.7) 235 | unicode-display_width (>= 1.4.0, < 1.7) 236 | rubocop-performance (1.5.2) 237 | rubocop (>= 0.71.0) 238 | ruby-progressbar (1.10.1) 239 | shotgun (0.9.2) 240 | rack (>= 1.0) 241 | text-table (1.2.4) 242 | thor (1.0.1) 243 | thread_safe (0.3.6) 244 | tzinfo (1.2.6) 245 | thread_safe (~> 0.1) 246 | unicode-display_width (1.6.0) 247 | xml-simple (1.1.5) 248 | xpath (3.2.0) 249 | nokogiri (~> 1.8) 250 | zeitwerk (2.2.2) 251 | 252 | PLATFORMS 253 | ruby 254 | 255 | DEPENDENCIES 256 | aws-ses 257 | byebug 258 | capybara 259 | dynomite 260 | jets 261 | launchy 262 | mysql2 (~> 0.5.2) 263 | pry 264 | rack 265 | rspec 266 | rubocop 267 | rubocop-performance 268 | shotgun 269 | 270 | BUNDLED WITH 271 | 2.0.2 272 | --------------------------------------------------------------------------------