30 Commits

Author SHA1 Message Date
413592a9d0 release workflow 2022-10-18 16:09:20 +02:00
1d9ed32438 cleanup 2022-10-18 15:50:12 +02:00
77884250ae version bump 2022-10-18 15:48:40 +02:00
91605aa434 drop support for commonjs 2022-10-18 15:48:27 +02:00
dbc5bf97d9 maybe this time 2022-10-18 15:42:55 +02:00
c2869e2746 cleanup 2022-10-18 15:37:16 +02:00
f587853432 versions bump 2022-10-18 15:36:28 +02:00
dffb5a7b13 packaging 2022-10-18 15:35:49 +02:00
07751ac477 add types legacy 2022-10-18 15:18:00 +02:00
877a0cd564 move types up 2022-10-18 15:07:38 +02:00
a2f0255895 move types up 2022-10-18 15:07:31 +02:00
f933df1908 build pipeline 2022-10-18 14:34:23 +02:00
ef44dab3bc add prepublish 2022-10-18 14:09:53 +02:00
70093a4ba8 use headless 2022-10-18 14:08:27 +02:00
5fde1797a5 update deps 2022-10-18 14:07:36 +02:00
f309294560 docs 2022-10-16 03:31:41 +02:00
062d8df713 readme 2022-10-16 03:27:08 +02:00
947c468cd4 fix playwright 2022-10-16 02:47:52 +02:00
f5f796cc13 testing with playwright 2022-10-16 02:45:17 +02:00
de042d485c rsa 2022-10-16 02:44:41 +02:00
6d58350575 cleanup 2022-10-14 17:34:02 +02:00
be4e736ffd aes 2022-10-14 17:32:05 +02:00
d52f59f709 readme 2022-10-14 15:10:46 +02:00
7fa0cbfe93 use typedarray everywhere and docs 2022-10-14 13:52:18 +02:00
d3b9e9bc42 delete docs 2022-10-14 13:44:38 +02:00
0c08dcc678 add hash as buffer 2022-10-14 13:31:52 +02:00
7a6a24d631 config stuff 2022-10-14 13:17:22 +02:00
75d702a5c7 sprcify version 2022-10-14 13:11:56 +02:00
4ee5666033 testing worklflow 2022-10-14 13:11:00 +02:00
c87fd3eaf5 rewrite 2022-10-13 22:06:51 +02:00
15 changed files with 468 additions and 682 deletions

View File

@@ -1,9 +1,7 @@
name: 'Publish to NPM'
name: "Publish to NPM"
on:
push:
tags:
- 'v*'
release:
jobs:
build:
@@ -16,11 +14,13 @@ jobs:
- name: Install Node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org'
node-version: 16
registry-url: "https://registry.npmjs.org"
- name: Setup PNPM
uses: pnpm/action-setup@v2
with:
version: 7
- name: Install dependencies
run: pnpm install
@@ -30,6 +30,6 @@ jobs:
run: pnpm run test
- name: Release
run: pnpm publish --no-git-checks
run: pnpm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -1,4 +1,4 @@
name: 'Run Tests'
name: "Run Tests"
on:
pull_request:
@@ -17,10 +17,12 @@ jobs:
- name: Install Node
uses: actions/setup-node@v3
with:
node-version-file: .nvmrc
node-version: 16
- name: Setup PNPM
uses: pnpm/action-setup@v2
with:
version: 7
- name: Install dependencies
run: pnpm install

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
engine-strict=true

1
.nvmrc
View File

@@ -1 +0,0 @@
v18.16

View File

@@ -5,18 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.0.2]
### Changed
- Updated dependencies.
## [2.0.1]
### Changed
- Updated dependencies.
## [2.0.0]
### Added

View File

@@ -33,10 +33,8 @@ npm i occulto
```typescript
import { RSA } from 'occulto'
const pair = await RSA.generateKeyPair(2 ** 11)
const bytes = Bytes.encode(message)
const encrypted = await RSA.encrypt(bytes, pair.public)
const pair = await RSA.generateKeyPair()
const encrypted = await RSA.encrypt('some text', pair.public)
const decrypted = await RSA.decrypt(encrypted, pair.private)
```
@@ -44,29 +42,11 @@ const decrypted = await RSA.decrypt(encrypted, pair.private)
[Available Modes](https://occulto.pages.dev/enums/Modes)
There is an _easy_ API, that will take care of everything for you.
```javascript
import { Symmetric } from 'occulto'
```typescript
import { AES } from 'occulto'
const password = 'foobar'
const message = 'this is a secret'
const encrypted = await AES.encryptEasy(message, password)
const decrypted = await AES.decryptEasy(encrypted, password)
```
The low level API is also exposed for advanced usages.
```typescript
import { AES } from 'occulto'
const message = 'this is a secret'
const key = await AES.generateKey()
const data = Bytes.encode(message)
const ciphertext = await AES.encrypt(data, key)
const plaintext = await AES.decrypt(ciphertext, key)
const encrypted = await Symmetric.encryptEasy('some string', 'myPass')
const decrypted = await Symmetric.decryptEasy(encrypted, 'myPass')
```
### [Hash](https://occulto.pages.dev/classes/Hash)
@@ -74,7 +54,9 @@ const plaintext = await AES.decrypt(ciphertext, key)
[Available hashes](https://occulto.pages.dev/enums/Hashes)
```typescript
import { Hash, Hashes } from 'occulto'
import { Hash } from 'occulto'
const hashed = await Hash.hash('Some value', Hashes.SHA_512)
const hash = Hash.digest('something')
const h = Hash.digest('something', Hash.Hashes.MD5)
```

View File

@@ -1,7 +1,6 @@
{
"name": "occulto",
"version": "2.0.2",
"packageManager": "pnpm@8.4.0",
"version": "2.0.0-rc.7",
"license": "MIT",
"description": "crypt utility",
"keywords": [
@@ -14,7 +13,7 @@
"node": ">=16",
"npm": "please-use-pnpm",
"yarn": "please-use-pnpm",
"pnpm": ">=8"
"pnpm": "7"
},
"type": "module",
"types": "./dist/index.d.ts",
@@ -42,15 +41,15 @@
},
"devDependencies": {
"@endyjasmi/karma-playwright-launcher": "^0.0.4",
"@types/node": "^20.1.5",
"chai": "^4.3.7",
"karma": "^6.4.2",
"@types/node": "^16.11.66",
"chai": "^4.3.6",
"karma": "^6.4.1",
"karma-mocha": "^2.0.1",
"mocha": "^10.2.0",
"mocha": "^10.1.0",
"npm-run-all": "^4.1.5",
"playwright": "^1.33.0",
"typedoc": "^0.24.7",
"typescript": "^5.0.4"
"playwright": "^1.27.1",
"typedoc": "^0.23.17",
"typescript": "^4.8.4"
},
"repository": {
"type": "git",

934
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,8 +29,7 @@ export enum Modes {
export class AES {
static Modes = Modes
// delimiter with a character that is not allowed in base64 or hex
private static delimiter = '--'
private static delimiter = '--' // delimiter with a character that is not allowed in base64 or hex
private static delimiterEasy = '---'
private static InvalidCiphertext = new Error('Invalid ciphertext')
@@ -142,18 +141,4 @@ export class AES {
const decrypted = await this.decrypt(data, keyDerived)
return Bytes.decode(decrypted)
}
static async generateKey(): Promise<TypedArray> {
const c = await getCrypto()
const key = await c.subtle.generateKey(
{
name: 'AES-GCM',
length: 256,
},
true,
['encrypt', 'decrypt']
)
const buffer = await c.subtle.exportKey('raw', key)
return new Uint8Array(buffer)
}
}

View File

@@ -3,4 +3,4 @@ export * from './crypto/encoding.js'
export * from './crypto/hash.js'
export * from './crypto/random.js'
export * from './crypto/rsa.js'
export { TypedArray } from './utils/base.js'
export * from './utils/base.js'

View File

@@ -2,42 +2,27 @@ import { AES, Bytes, Hashes, Hex } from '../dist/index.js'
import { Precomputed } from './values.js'
describe('AES', () => {
for (const message of Object.values(Precomputed.Crypto.Messages)) {
describe(`Message: ${message.slice(0, 8)}...`, () => {
describe('Basic API', () => {
for (const keySize of [128, 256]) {
it('Key Size: ' + keySize, async () => {
const data = Bytes.encode(message)
const [key] = await AES.derive('foo', {
name: 'PBKDF2',
hash: Hashes.SHA_512,
iterations: 1000,
length: keySize,
salt: Hex.decode(Precomputed.Crypto.Bytes[16]),
})
const ciphertext = await AES.encrypt(data, key, AES.Modes.GCM)
const plaintext = await AES.decrypt(ciphertext, key)
chai.expect(data).to.be.deep.equal(plaintext)
chai.expect(message).to.be.equal(Bytes.decode(plaintext))
})
}
})
it('Generated Key', async () => {
const key = await AES.generateKey()
const data = Bytes.encode(message)
const ciphertext = await AES.encrypt(data, key)
const plaintext = await AES.decrypt(ciphertext, key)
chai.expect(data).to.be.deep.equal(plaintext)
chai.expect(message).to.be.equal(Bytes.decode(plaintext))
})
it('Easy API', async () => {
const password = 'foobar'
const encrypted = await AES.encryptEasy(message, password)
const decrypted = await AES.decryptEasy(encrypted, password)
chai.expect(message).to.be.equal(decrypted)
})
it('Basic API', async () => {
const message = Precomputed.Crypto.Messages.nietzscheIpsum
const data = Bytes.encode(message)
const [key] = await AES.derive('foo', {
name: 'PBKDF2',
hash: Hashes.SHA_512,
iterations: 1000,
length: 256,
salt: Hex.decode(Precomputed.Crypto.Bytes[16]),
})
}
const ciphertext = await AES.encrypt(data, key, AES.Modes.GCM)
const plaintext = await AES.decrypt(ciphertext, key)
chai.expect(data).to.be.deep.equal(plaintext)
chai.expect(message).to.be.equal(Bytes.decode(plaintext))
})
it('Easy API', async () => {
const message = Precomputed.Crypto.Messages.nietzscheIpsum
const password = 'foobar'
const encrypted = await AES.encryptEasy(message, password)
const decrypted = await AES.decryptEasy(encrypted, password)
chai.expect(message).to.be.equal(decrypted)
})
})

View File

@@ -1,29 +1,7 @@
import { Base64, Bytes, Hex } from '../dist/index.js'
import { compareArrayLike } from './utils.js'
import { Base64, Bytes } from '../dist/index.js'
import { Precomputed } from './values.js'
describe('Encoding', () => {
describe('Bytes', () => {
for (const [input, output] of Object.entries(Precomputed.Encoding.Bytes)) {
it(`Should encode ${input} to ${output}`, async () => {
compareArrayLike(Bytes.encode(input), output)
})
it(`Should decode ${output} to ${input}`, async () => {
compareArrayLike(await Bytes.decode(output), input)
})
}
})
describe('Hex', () => {
for (const [input, output] of Object.entries(Precomputed.Encoding.Hex)) {
const buffer = Bytes.encode(input)
it(`Should encode ${input} to ${output}`, async () => {
chai.expect(await Hex.encode(buffer)).to.equal(output)
})
it(`Should decode ${output} to ${input}`, async () => {
chai.expect(await Hex.decode(output)).to.deep.equal(buffer)
})
}
})
describe('Base64', () => {
for (const [input, output] of Object.entries(Precomputed.Encoding.Base64)) {
const buffer = Bytes.encode(input)

View File

@@ -4,7 +4,7 @@ import { Precomputed } from './values.js'
describe('RSA', () => {
describe('Generate keys', function () {
this.timeout(10_000)
this.timeout(5_000)
it('Should be able to generate a keypair', async () => {
await RSA.generateKeyPair()

View File

@@ -6,10 +6,3 @@ export class Promises {
} catch {}
}
}
export function compareArrayLike(a, b) {
chai.expect(a.length).to.equal(b.length)
for (let i = 0; i < a.length; i++) {
chai.expect(a[i]).to.equal(b[i])
}
}

View File

@@ -5,18 +5,6 @@ export const Precomputed = {
test: 'dGVzdA==',
'hello world': 'aGVsbG8gd29ybGQ=',
},
Hex: {
test: '74657374',
occulto: '6f6363756c746f',
'hello world': '68656c6c6f20776f726c64',
},
Bytes: {
test: new Uint8Array([0x74, 0x65, 0x73, 0x74]),
occulto: new Uint8Array([0x6f, 0x63, 0x63, 0x75, 0x6c, 0x74, 0x6f]),
'entropy is king': new Uint8Array([
0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x20, 0x69, 0x73, 0x20, 0x6b, 0x69, 0x6e, 0x67,
]),
},
},
Hash: {
SHA_1: {
@@ -51,8 +39,6 @@ export const Precomputed = {
},
Messages: {
test: 'test',
occulto: 'occulto',
weird: 'Some 🃏 weird 🃏 text',
nietzscheIpsum:
'Marvelous intentions joy deceptions overcome sexuality spirit against. Selfish of marvelous play dead war snare eternal-return ultimate. Reason aversion suicide.',
},