Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop use of self-signed certs (which are now expired), fixes #176 #179

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ Hello! After a bit of a hiatus, the [Architect team](https://github.com/architec
- Added `--verbose|-v` / `options.verbose`, `--debug|-d` / `options.debug` logging modes, and some additional logging
- Added `-h` help alias for CLI
- Added Typescript Types via JSDOC comments
- Enabled `port` and `host` options to be passed to Dynalite in `http` mode (instead of needing to be set in `dynalite.listen(port, host)`)


### Changed

- [Breaking change] Introduced minimum Node.js version of >= 14; fixes [#169](https://github.com/architect/dynalite/issues/169)
- [Breaking change] When using SSL mode, you must now supply your own `key`, `cert`, and `ca` (which isn't much of a breaking change, really, because Dynalite's certs were expired); fixes [#176](https://github.com/architect/dynalite/issues/176)
- In CLI mode, pass them as file paths with flags (e.g. `--key /foo/key.pem --cert /foo/cert.pem --ca /foo/ca-cert.pem`)
- As a module, you can pass them as strings or as file paths; when passing as file paths, make sure you include a boolean `useSSLFilePaths` option
- Changed license from MIT to Apache 2.0; see [#166](https://github.com/architect/dynalite/issues/166)
- Updated dependencies (which themselves dropped support for older versions of Node.js)
- Updated tests
Expand Down
1 change: 1 addition & 0 deletions cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ if (argv.help || argv.h) {
'--port <port> The port to listen on (default: 4567)',
'--path <path> The path to use for the LevelDB store (in-memory by default)',
'--ssl Enable SSL for the web server (default: false)',
' Pass cert file paths with --key, --cert, and --ca',
'--createTableMs <ms> Amount of time tables stay in CREATING state (default: 500)',
'--deleteTableMs <ms> Amount of time tables stay in DELETING state (default: 500)',
'--updateTableMs <ms> Amount of time tables stay in UPDATING state (default: 500)',
Expand Down
54 changes: 31 additions & 23 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
var http = require('http'),
https = require('https'),
fs = require('fs'),
path = require('path'),
url = require('url'),
crypto = require('crypto'),
crc32 = require('buffer-crc32'),
validations = require('./validations'),
db = require('./db')

var MAX_REQUEST_BYTES = 16 * 1024 * 1024
var verbose = false
var debug = false
let { readFileSync } = require('fs')
let url = require('url')
let crypto = require('crypto')
let crc32 = require('buffer-crc32')
let validations = require('./validations')
let db = require('./db')

const MAX_REQUEST_BYTES = 16 * 1024 * 1024
let verbose = false
let debug = false

var validApis = [ 'DynamoDB_20111205', 'DynamoDB_20120810' ],
validOperations = [ 'BatchGetItem', 'BatchWriteItem', 'CreateTable', 'DeleteItem', 'DeleteTable',
Expand All @@ -19,16 +16,15 @@ var validApis = [ 'DynamoDB_20111205', 'DynamoDB_20120810' ],
actions = {},
actionValidations = {}

module.exports = dynalite

/**
* @param {Object} options - The shape is the same as SpecialType above
* @param {boolean} [options.verbose=false] - Enable verbose logging
* @param {boolean} [options.debug=false] - Enable debug logging
* @param {boolean} [options.ssl=false] - Enable SSL for the web server
* @param {string} [options.key] - SSL private key - if omitted and ssl enabled, self-signed cert will be used
* @param {string} [options.cert] - SSL certificate - if omitted and ssl enabled, self-signed cert will be used
* @param {string} [options.ca] - SSL certificate authority - if omitted and ssl enabled, self-signed cert will be used
* @param {string} [options.key] - SSL private key; to use a file path instead, pass the useSSLFilePaths option
* @param {string} [options.cert] - SSL certificate; to use a file path instead, pass the useSSLFilePaths option
* @param {string} [options.ca] - SSL certificate authority; to use a file path instead, pass the useSSLFilePaths option
* @param {boolean} [options.useSSLFilePaths] - Use file paths instead of strings for SSL certs
* @param {number} [options.createTableMs=500] - Amount of time tables stay in CREATING state
* @param {number} [options.deleteTableMs=500] - Amount of time tables stay in DELETING state
* @param {number} [options.updateTableMs=500] - Amount of time tables stay in UPDATING state
Expand All @@ -45,17 +41,28 @@ function dynalite (options) {
var server, store = db.create(options), requestHandler = httpHandler.bind(null, store)

if (options.ssl) {
options.key = options.key || fs.readFileSync(path.join(__dirname, 'ssl', 'server-key.pem'))
options.cert = options.cert || fs.readFileSync(path.join(__dirname, 'ssl', 'server-crt.pem'))
options.ca = options.ca || fs.readFileSync(path.join(__dirname, 'ssl', 'ca-crt.pem'))
let useFilePath = options.useSSLFilePaths || options._
let files = [ 'key', 'cert', 'ca' ]
files.forEach(file => {
if (!options[file]) throw ReferenceError(`SSL must have '${file}' option`)
})
options.key = useFilePath ? readFileSync(options.key) : options.key
options.cert = useFilePath ? readFileSync(options.cert) : options.cert
options.ca = useFilePath ? readFileSync(options.ca) : options.ca

// eslint-disable-next-line
let https = require('https')
server = https.createServer(options, requestHandler)
}
else {
server = http.createServer(requestHandler)
// eslint-disable-next-line
let http = require('http')
server = http.createServer(options, requestHandler)
}

// Ensure we close DB when we're closing the server too
var httpServerClose = server.close, httpServerListen = server.listen
let httpServerClose = server.close
let httpServerListen = server.listen
server.close = function (cb) {
store.db.close(function (err) {
if (err) return cb(err)
Expand Down Expand Up @@ -303,4 +310,5 @@ function httpHandler (store, req, res) {
})
}

module.exports = dynalite
if (require.main === module) dynalite().listen(4567)
26 changes: 21 additions & 5 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# dynalite
# Dynalite

[![GitHub CI status](https://github.com/architect/dynalite/workflows/Node%20CI/badge.svg)](https://github.com/architect/dynalite/actions?query=workflow%3A%22Node+CI%22)

Expand All @@ -9,6 +9,7 @@ for fast in-memory or persistent usage.
This project aims to match the live DynamoDB instances as closely as possible
(and is tested against them in various regions), including all limits and error messages.


## What about Amazon's DynamoDB Local?

This project was created before DynamoDB Local existed, and when it did, it differed a lot from the live instances
Expand All @@ -17,6 +18,7 @@ and is probably more up-to-date than dynalite is. I'd recommend using it over dy
overhead of starting the JVM (or docker) each time. If you need a fast in-memory option that you can start up in
milliseconds, then dynalite might be more suitable for you.


## Example

```sh
Expand All @@ -32,6 +34,7 @@ Options:
--port <port> The port to listen on (default: 4567)
--path <path> The path to use for the LevelDB store (in-memory by default)
--ssl Enable SSL for the web server (default: false)
Pass cert file paths with --key, --cert, and --ca
--createTableMs <ms> Amount of time tables stay in CREATING state (default: 500)
--deleteTableMs <ms> Amount of time tables stay in DELETING state (default: 500)
--updateTableMs <ms> Amount of time tables stay in UPDATING state (default: 500)
Expand All @@ -46,8 +49,8 @@ Or programmatically:

```js
// Returns a standard Node.js HTTP server
var dynalite = require('dynalite')
var dynaliteServer = dynalite({ path: './mydb', createTableMs: 50 })
const dynalite = require('dynalite')
const dynaliteServer = dynalite()

// Listen on port 4567
dynaliteServer.listen(4567, function(err) {
Expand All @@ -56,17 +59,30 @@ dynaliteServer.listen(4567, function(err) {
})
```

```js
// Use Dynalite in HTTPS mode
const dynalite = require('dynalite')
const dynaliteServer = dynalite({
ssl: true,
key: 'Your private key in PEM format...',
cert: 'Your cert chain in PEM format...',
ca: 'Your CA certificate string...',
// Alternately, pass `useSSLFilePaths: true` to use file paths for `key`, `cert`, and `ca`
})
```

Once running, here's how you use the [AWS SDK](https://github.com/aws/aws-sdk-js) to connect
(after [configuring the SDK](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/configuring-the-jssdk.html)):

```js
var AWS = require('aws-sdk')
const AWS = require('aws-sdk')

var dynamo = new AWS.DynamoDB({ endpoint: 'http://localhost:4567' })
const dynamo = new AWS.DynamoDB({ endpoint: 'http://localhost:4567' })

dynamo.listTables(console.log.bind(console))
```


## Installation

With [npm](https://www.npmjs.com/), to install the CLI:
Expand Down
54 changes: 0 additions & 54 deletions ssl/ca-key.pem

This file was deleted.

28 changes: 0 additions & 28 deletions ssl/server-csr.pem

This file was deleted.

11 changes: 9 additions & 2 deletions test/connection.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
var https = require('https'),
once = require('once'),
dynalite = require('..'),
helpers = require('./helpers')
helpers = require('./helpers'),
path = require('path')

var request = helpers.request

Expand Down Expand Up @@ -109,7 +110,13 @@ describe('dynalite connections', function () {
})

it('should connect to SSL', function (done) {
var port = 10000 + Math.round(Math.random() * 10000), dynaliteServer = dynalite({ ssl: true })
var port = 10000 + Math.round(Math.random() * 10000), dynaliteServer = dynalite({
ssl: true,
useSSLFilePaths: true,
key: path.join(__dirname, 'ssl', 'server-key.pem'),
cert: path.join(__dirname, 'ssl', 'server-crt.pem'),
ca: path.join(__dirname, 'ssl', 'ca-crt.pem'),
})

dynaliteServer.listen(port, function (err) {
if (err) return done(err)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.