Skip to content

Commit

Permalink
Drop use of self-signed certs (which are now expired), fixes #176
Browse files Browse the repository at this point in the history
Add `--key`, `--cert`, `--ca` CLI flags, and `useSSLFilePaths` API option
Only require `http` or `https`, but not both
Update types
Fix `--port` + `--host` not being passed in `http` mode; fixes #178
  • Loading branch information
ryanblock committed Sep 5, 2023
1 parent 944f77e commit 3bd330d
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 112 deletions.
8 changes: 8 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ Hello! After a bit of a hiatus, the [Architect team](https://github.com/architec
### 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
- Added Architect Code of Conduct, new CI flow, etc.


### Fixed

- Fixed CLI `--port` (and `--host`) options not being passed to Dynalite in `http` mode; fixes [#178](https://github.com/architect/dynalite/issues/178)

---

## [3.2.2 (and prior)]
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.

0 comments on commit 3bd330d

Please sign in to comment.