Skip to content

Commit

Permalink
feat: initial release
Browse files Browse the repository at this point in the history
Release-As: 0.1.0
  • Loading branch information
nhedger committed Aug 24, 2023
0 parents commit 9205a14
Show file tree
Hide file tree
Showing 25 changed files with 3,325 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
charset = utf-8
indent_size = 4
indent_style = tab
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.{yml,yaml}]
indent_style = space
indent_size = 2

[*.md]
max_line_length = 120
1 change: 1 addition & 0 deletions .github/FUNDING.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: [nhedger]
27 changes: 27 additions & 0 deletions .github/actions/setup/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Setup
description: Sets up the job
runs:
using: composite
steps:
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: 20
- name: Set up pnpm
uses: pnpm/action-setup@v2.2.4
with:
version: latest
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-pnpm-
- name: Install dependencies
shell: bash
run: pnpm install
8 changes: 8 additions & 0 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base", "schedule:weekly"],
"ignorePresets": [":semanticPrefixFixDepsChoreOthers"],
"labels": ["dependencies"],
"rangeStrategy": "pin",
"semanticCommitType": "deps"
}
45 changes: 45 additions & 0 deletions .github/workflows/integrate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Integrate

on:
push:
tags-ignore: ["*"]
pull_request:
workflow_call:
workflow_dispatch:

env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

jobs:
coding-standards:
name: Standards
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up
uses: ./.github/actions/setup
- name: Run Rome
run: pnpm exec -- rome ci .

build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up
uses: ./.github/actions/setup
- name: Build
run: pnpm build

test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up
uses: ./.github/actions/setup
- name: Run Vitest
run: pnpm test
35 changes: 35 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Publish

on:
workflow_call:
inputs:
version:
required: true
type: string
tag_name:
required: true
type: string

env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

jobs:
publish:
name: Publish to NPM
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up
uses: ./.github/actions/setup
- name: Build
run: pnpm build
- name: Set publish config
run: pnpm config set '//registry.npmjs.org/:_authToken' "${NODE_AUTH_TOKEN}"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Publish
run: pnpm publish
40 changes: 40 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Release

on:
push:
branches: ["main"]

jobs:
integrate:
name: Integrate
uses: ./.github/workflows/integrate.yaml

release:
name: Release
needs: ["integrate"]
runs-on: ubuntu-latest
steps:
- id: release
name: Run release-please
uses: google-github-actions/release-please-action@v3.7.11
with:
release-type: node
package-name: "@hedger/nestjs-encryption"
pull-request-header: "Upcoming release"
pull-request-title-pattern: "chore: release${component} ${version}"
outputs:
tag_name: ${{ steps.release.outputs.tag_name }}
release_created: ${{ steps.release.outputs.release_created }}
version:
"${{ steps.release.outputs.major }}.${{ steps.release.outputs.minor
}}.${{ steps.release.outputs.patch }}"

publish:
name: Publish
if: ${{ needs.release.outputs.release_created == 'true' }}
needs: ["release"]
uses: ./.github/workflows/publish.yaml
secrets: inherit
with:
tag_name: ${{ needs.release.outputs.tag_name }}
version: ${{ needs.release.outputs.version }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/coverage/
/dist/
/node_modules/
3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["rome.rome", "zixuanchen.vitest-explorer"]
}
20 changes: 20 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# The MIT License (MIT)

Copyright © `2023` `Nicolas Hedger`

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the “Software”), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
147 changes: 147 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# NestJS Encryption Module

**NestJS Encrytion** is NestJS 9+ module that provides _plug-and-play_ encryption
and decryption functionality to your NestJS application.

- Uses `AES-256-CBC` by default, but supports [other ciphers](#supported-ciphers) as well.
- Provides a keygen (API and CLI) for generating random and secure encryption keys.
- Thoroughly tested.

## Installation

**NestJS Encryption** can be installed with your favorite package manager.

```bash
# NPM
npm install @hedger/nestjs-encryption

# Yarn
yarn add @hedger/nestjs-encryption

# PNPM
pnpm add @hedger/nestjs-encryption
```

## Setup

Setting up the module inside your NestJS application is a matter of registering
the module within your `AppModule`.

You may use either the `register` or `registerAsync` method to register the module in your `AppModule`.

### Using `register`

The `register` method is the simplest way to register the module.

```typescript
import { EncryptionModule, Cipher } from "@hedger/nestjs-encryption";

@Module({
imports: [
EncryptionModule.register({
key: process.env.APP_KEY,
cipher: Cipher.AES_256_CBC,
}),
],
})
export class AppModule {}
```

### Using `registerAsync`

The `registerAsync` method allows you to register the module asynchronously,
optionally resolving the encryption key from a configuration service. Here's
an example that uses the `ConfigService` from `@nestjs/config` to resolve the
encryption key from the `APP_KEY` environment variable.

```typescript
import { ConfigModule, ConfigService } from "@nestjs/config";
import { EncryptionModule, Cipher } from "@hedger/nestjs-encryption";

@Module({
imports: [
ConfigModule.forRoot(),
EncryptionModule.registerAsync({
useFactory: (config: ConfigService) => ({
key: config.get("APP_KEY"),
cipher: Cipher.AES_256_CBC,
}),
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
```

## Usage

Inject the EncryptionService in your service or controller.

```typescript
import { EncryptionService } from "@hedger/nestjs-encryption";

@Injectable()
export class FooService {
constructor(private readonly crypto: EncryptionService) {}

someMethod() {
const encrypted = this.crypto.encrypt("some value");
const decrypted = this.crypto.decrypt(encrypted);
}
}
```

## Encryption key

This package expects the encryption key to be a base64-encoded string of N random
bytes, where N is the key length of the cipher you're using. For example, the
`aes-256-cbc` cipher has a key length of 32 bytes, so the encryption key must
be a base64-encoded string of 32 random bytes.

### Generating a key

This package provides CLI utility for generating random and secure encryption
keys.

```bash
# Generates a random key for the aes-256-cbc cipher (default)
npm exec nestjs-encryption-keygen
```

By default, the keygen generates keys for the `aes-256-cbc` cipher. You may
specify a different cipher by passing the `--cipher` option.

```bash
# Generates a random key for the aes-128-cbc cipher
npm exec nestjs-encryption-keygen --cipher aes-128-cbc
```

See the [Supported ciphers](#supported-ciphers) section for a list of supported
ciphers.

### Generating a key programmatically

Random and secure encryption keys may also be generated programmatically by
calling the `generateKey` method on the `EncryptionService` class.

```typescript
import { Cipher, EncryptionService } from "@hedger/nestjs-encryption";

// Pass the desired cipher as the first argument.
const key = EncryptionService.generateKey(Cipher.AES_256_CBC);
```

## Supported ciphers

The following ciphers are supported by this package.

- `aes-256-cbc` (default)
- `aes-256-gcm`
- `aes-128-cbc`
- `aes-128-gcm`

## License

Copyright © 2023, [Nicolas Hedger](https://github.com/nhedger). Released under the [MIT License](LICENSE.md).
21 changes: 21 additions & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
entries: ["src/lib/index", "src/cli/keygen"],
declaration: true,
clean: true,
rollup: {
emitCJS: true,
esbuild: {
tsconfigRaw: {
compilerOptions: {
target: "es2021",
experimentalDecorators: true,
},
},
},
},
alias: {
"@/": "src/",
},
});
6 changes: 6 additions & 0 deletions lefthook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pre-commit:
commands:
format:
run: pnpm exec -- rome format --write . && git add {staged_files}
lint:
run: pnpm exec -- rome check .

0 comments on commit 9205a14

Please sign in to comment.