Skip to content

Commit 44a5ff9

Browse files
committed
fix
1 parent 55666ba commit 44a5ff9

4 files changed

Lines changed: 43 additions & 9 deletions

File tree

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
> [!WARNING]
44
> This package uses [`Uint8Array.prototype.toBase64()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64) and [`Uint8Array.fromBase64()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64), which, as of November 2025, are only supported by the latest versions of browsers, [Bun](https://bun.com/), [Deno 2.5 or later](https://deno.com/) and [Node.js 25 or later](https://nodejs.org/en). See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64#browser_compatibility) for compatibility.
55
6-
A simple, secure, and fast symmetric encryption library that makes use of [AES-GCM](https://en.wikipedia.org/wiki/Galois/Counter_Mode) and modern platform features. It leverages the native [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API), so it works both in browsers and JavaScript runtimes.
6+
A simple, secure, and fast symmetric encryption library that makes use of [AES-GCM](https://en.wikipedia.org/wiki/Galois/Counter_Mode) and modern platform features. It leverages the native [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API), so it works both in browsers (in secure contexts) and JavaScript runtimes.
77

88
## Why AES-GCM?
99

@@ -45,7 +45,10 @@ import { getMessageEncryptionKey } from "./lib/crypto/key";
4545

4646
export const cryptoMessage = new SingleCryptText(
4747
await getMessageEncryptionKey()
48-
)
48+
);
49+
50+
// Recommended: Freeze the instance to prevent modification of the `urlSafe` property.
51+
Object.freeze(cryptoMessage);
4952
```
5053

5154
#### Usage
@@ -197,6 +200,9 @@ new SingleCryptText(
197200

198201
- `urlSafe: boolean`
199202
Indicates if the instance uses `base64url` encoding (`true`, default) or standard `base64` (`false`) for encrypted outputs.
203+
204+
> [!NOTE]
205+
> It is recommended to freeze `SingleCryptText` instances with `Object.freeze()` to prevent its modification.
200206
201207

202208
#### Example

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ export class SingleCryptText {
199199
* - The operation failed (e.g., AES-GCM plaintext longer than 2^39−256 bytes).
200200
*/
201201
async encrypt(text) {
202-
return encryptTextSymmetrically(await this.getKey(), text, this.urlSafe, this.#textEncoder)
202+
return await encryptTextSymmetrically(await this.getKey(), text, this.urlSafe, this.#textEncoder)
203203
}
204204

205205
/**
@@ -213,7 +213,7 @@ export class SingleCryptText {
213213
* - The operation failed.
214214
*/
215215
async decrypt(encryptedText) {
216-
return decryptTextSymmetrically(await this.getKey(), encryptedText, this.urlSafe, this.#textDecoder)
216+
return await decryptTextSymmetrically(await this.getKey(), encryptedText, this.urlSafe, this.#textDecoder)
217217
}
218218

219219
}

index.test.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe("Functional", () => {
4545
const symCryptoKey2 = await createSymmetricKeyFromText(randomString())
4646
const randomValue = randomString()
4747
const encrypted = await encryptTextSymmetrically(symCryptoKey, randomValue)
48-
expect(async() => await decryptTextSymmetrically(symCryptoKey2, encrypted)).toThrowError()
48+
await expect(decryptTextSymmetrically(symCryptoKey2, encrypted)).rejects.toThrow()
4949
})
5050

5151
test("Check if disabling `urlSafe` changes the encryption results.", async() => {
@@ -58,8 +58,8 @@ describe("Functional", () => {
5858
const decryptedUrlUnafe = await decryptTextSymmetrically(symCryptoKey, encryptedUrlUnsafe, false)
5959
expect(randomValue).toBe(decryptedUrlSafe)
6060
expect(randomValue).toBe(decryptedUrlUnafe)
61-
expect(async() => await decryptTextSymmetrically(symCryptoKey, encryptedUrlSafe, false)).toThrowError()
62-
expect(async() => await decryptTextSymmetrically(symCryptoKey, encryptedUrlUnsafe, true)).toThrowError()
61+
await expect(decryptTextSymmetrically(symCryptoKey, encryptedUrlSafe, false)).rejects.toThrow()
62+
await expect(decryptTextSymmetrically(symCryptoKey, encryptedUrlUnsafe, true)).rejects.toThrow()
6363
})
6464

6565
})
@@ -69,11 +69,38 @@ describe("Object-oriented", () => {
6969

7070
const singleCryptText1 = new SingleCryptText(randomString())
7171

72-
test("Decrypt a random value", async() => {
72+
test("Encrypt and decrypt random values", async() => {
73+
const randomValue = randomString()
74+
const encrypted = await singleCryptText1.encrypt(randomValue)
75+
const decrypted = await singleCryptText1.decrypt(encrypted)
76+
expect(randomValue).toBe(decrypted)
77+
let randomValue2
78+
do {
79+
randomValue2 = randomString()
80+
} while (randomValue === randomValue2)
81+
const encrypted2 = await singleCryptText1.encrypt(randomValue2)
82+
expect(encrypted).not.toBe(encrypted2)
83+
const decrypted2 = await singleCryptText1.decrypt(encrypted2)
84+
expect(decrypted).not.toBe(decrypted2)
85+
expect(randomValue2).toBe(decrypted2)
86+
})
87+
88+
test("Check if `urlSafe` property works", async() => {
7389
const randomValue = randomString()
7490
const encrypted = await singleCryptText1.encrypt(randomValue)
91+
singleCryptText1.urlSafe = !singleCryptText1.urlSafe
92+
await expect(singleCryptText1.decrypt(encrypted)).rejects.toThrow()
93+
singleCryptText1.urlSafe = !singleCryptText1.urlSafe
7594
const decrypted = await singleCryptText1.decrypt(encrypted)
7695
expect(randomValue).toBe(decrypted)
96+
singleCryptText1.urlSafe = !singleCryptText1.urlSafe
97+
const encrypted2 = await singleCryptText1.encrypt(randomValue)
98+
expect(encrypted).not.toBe(encrypted2)
99+
singleCryptText1.urlSafe = !singleCryptText1.urlSafe
100+
await expect(singleCryptText1.decrypt(encrypted2)).rejects.toThrow()
101+
singleCryptText1.urlSafe = !singleCryptText1.urlSafe
102+
const decrypted2 = await singleCryptText1.decrypt(encrypted2)
103+
expect(randomValue).toBe(decrypted2)
77104
})
78105

79106
})

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "singlecrypt-text",
3-
"version": "3.0.2",
3+
"version": "3.0.3",
44
"author": "Stefan Samson <ss42701@outlook.com> (https://ssbit01.github.io/)",
55
"repository": "github:SSbit01/singlecrypt-text",
66
"main": "index.js",
@@ -44,6 +44,7 @@
4444
"private": false,
4545
"scripts": {
4646
"test": "bun test",
47+
"test:random": "bun test --randomize",
4748
"build:types": "tsc",
4849
"build": "bun build ./index.js --minify --target browser --outdir ./dist --entry-naming [dir]/[name].min.[ext]",
4950
"build:cjs": "bun build ./index.js --minify --format cjs --outdir ./dist --entry-naming [dir]/[name].node.min.[ext]"

0 commit comments

Comments
 (0)