From 76599e5f0703df867e21dc2c6ee497f8c12a2e0f Mon Sep 17 00:00:00 2001 From: CJ Brewer Date: Wed, 5 Feb 2025 14:36:18 -0700 Subject: [PATCH 1/2] feat: rebrand jseql to protect --- .changeset/smooth-walls-camp.md | 7 + CONTRIBUTE.md | 28 ++-- README.md | 138 ++++++++---------- apps/basic/README.md | 8 +- apps/basic/index.mjs | 8 +- apps/basic/package.json | 2 +- apps/drizzle/drizzle.config.ts | 2 +- apps/drizzle/drizzle/meta/0000_snapshot.json | 6 +- apps/drizzle/drizzle/meta/_journal.json | 2 +- apps/drizzle/package.json | 2 +- apps/drizzle/src/db/schema.ts | 2 +- apps/drizzle/src/eql.ts | 4 - apps/drizzle/src/insert.ts | 4 +- apps/drizzle/src/protect.ts | 4 + apps/drizzle/src/select.ts | 6 +- apps/hono-supabase/README.md | 24 +-- apps/hono-supabase/package.json | 2 +- apps/hono-supabase/tsconfig.json | 8 +- package.json | 8 +- packages/jseql/README.md | 4 +- packages/jseql/src/index.ts | 11 -- packages/nextjs/README.md | 4 + packages/nextjs/__tests__/nextjs.test.ts | 10 +- packages/nextjs/package.json | 6 +- packages/nextjs/src/clerk/index.ts | 6 +- packages/nextjs/src/cts/index.ts | 2 +- packages/nextjs/src/index.ts | 8 +- packages/{jseql => protect}/CHANGELOG.md | 0 packages/protect/README.md | 4 + .../__tests__/jseql.test.ts | 46 +++--- .../cs_plaintext_v1.schema.json | 22 +-- .../{jseql => protect}/generateSchema.mjs | 0 packages/{jseql => protect}/package.json | 10 +- .../{jseql => protect}/src/cs_plaintext_v1.ts | 0 packages/{jseql => protect}/src/eql/index.ts | 6 +- .../{jseql => protect}/src/ffi/env-check.ts | 0 packages/{jseql => protect}/src/ffi/index.ts | 16 +- .../src/ffi/payload-helpers.ts | 4 +- .../{jseql => protect}/src/identify/index.ts | 0 packages/protect/src/index.ts | 11 ++ .../{jseql => protect}/tsconfig.jest.json | 0 packages/{jseql => protect}/tsconfig.json | 0 packages/{jseql => protect}/tsup.config.ts | 0 packages/utils/logger/index.ts | 2 +- pnpm-lock.yaml | 52 +++---- 45 files changed, 236 insertions(+), 253 deletions(-) create mode 100644 .changeset/smooth-walls-camp.md delete mode 100644 apps/drizzle/src/eql.ts create mode 100644 apps/drizzle/src/protect.ts delete mode 100644 packages/jseql/src/index.ts create mode 100644 packages/nextjs/README.md rename packages/{jseql => protect}/CHANGELOG.md (100%) create mode 100644 packages/protect/README.md rename packages/{jseql => protect}/__tests__/jseql.test.ts (83%) rename packages/{jseql => protect}/cs_plaintext_v1.schema.json (82%) rename packages/{jseql => protect}/generateSchema.mjs (100%) rename packages/{jseql => protect}/package.json (83%) rename packages/{jseql => protect}/src/cs_plaintext_v1.ts (100%) rename packages/{jseql => protect}/src/eql/index.ts (100%) rename packages/{jseql => protect}/src/ffi/env-check.ts (100%) rename packages/{jseql => protect}/src/ffi/index.ts (99%) rename packages/{jseql => protect}/src/ffi/payload-helpers.ts (100%) rename packages/{jseql => protect}/src/identify/index.ts (100%) create mode 100644 packages/protect/src/index.ts rename packages/{jseql => protect}/tsconfig.jest.json (100%) rename packages/{jseql => protect}/tsconfig.json (100%) rename packages/{jseql => protect}/tsup.config.ts (100%) diff --git a/.changeset/smooth-walls-camp.md b/.changeset/smooth-walls-camp.md new file mode 100644 index 00000000..5fff020c --- /dev/null +++ b/.changeset/smooth-walls-camp.md @@ -0,0 +1,7 @@ +--- +"@cipherstash/nextjs": major +"@cipherstash/basic-example": major +"@cipherstash/protect": major +--- + +Rebrand jseql to protect. diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md index 24bc15a2..4b48eaa6 100644 --- a/CONTRIBUTE.md +++ b/CONTRIBUTE.md @@ -1,16 +1,16 @@ -# How to contribute to jseql +# How to contribute to @cipherstash/protect ## I want to report a bug, or make a feature request Please use the GitHub issue tracker to report bugs, suggest features, or documentation improvements. -[When filing an issue](https://github.com/cipherstash/jseql/issues/new/choose), please check [existing open](https://github.com/cipherstash/jseql/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc), or [recently closed](https://github.com/cipherstash/jseql/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aclosed), issues to make sure somebody else hasn't already reported the issue. Please try to include as much information as you can. +[When filing an issue](https://github.com/cipherstash/protectjs/issues/new/choose), please check [existing open](https://github.com/cipherstash/protectjs/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc), or [recently closed](https://github.com/cipherstash/protectjs/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aclosed), issues to make sure somebody else hasn't already reported the issue. Please try to include as much information as you can. --- -# Contributing to JSEQL +# Contributing to @cipherstash/protect -Thank you for your interest in contributing to **jseql**! This document will walk you through the repository’s structure, how to build and run the project locally, and how to make contributions effectively. +Thank you for your interest in contributing to **@cipherstash/protect**! This document will walk you through the repository’s structure, how to build and run the project locally, and how to make contributions effectively. ## Repository Structure @@ -21,7 +21,7 @@ Thank you for your interest in contributing to **jseql**! This document will wal │ └── example-app-2/ │ ├── packages/ -│ └── jseql/ <-- Main package published to npm +│ └── protect/ <-- Main package published to npm │ ├── .changeset/ ├── .turbo/ @@ -34,21 +34,21 @@ Thank you for your interest in contributing to **jseql**! This document will wal This repo uses [Turborepo](https://turbo.build/) to manage multiple packages and apps in a monorepo structure. Turborepo orchestrates tasks (build, test, lint, etc.) across the different packages in a consistent and efficient manner. -### `packages/jseql` +### `packages/protect` -The **jseql** package is the core library that is published to npm under the `@cipherstash/jseql` namespace. This is likely where you’ll spend most of your time if you’re contributing new features or bug fixes related to JSEQL’s core functionality. +The **@cipherstash/protect** package is the core library that is published to npm under the `@cipherstash/protect` namespace. This is likely where you’ll spend most of your time if you’re contributing new features or bug fixes related to JSEQL’s core functionality. ### `apps/` Directory -Within the `apps/` directory, you’ll find example applications that demonstrate how to use **jseql**. These example apps reference the local `@cipherstash/jseql` package, allowing you to test and verify your changes to **jseql** in a real-world application scenario. +Within the `apps/` directory, you’ll find example applications that demonstrate how to use **@cipherstash/protect**. These example apps reference the local `@cipherstash/protect` package, allowing you to test and verify your changes to **@cipherstash/protect** in a real-world application scenario. ## Setup Instructions ### 1. Clone the Repo ```bash -git clone https://github.com/cipherstash/jseql.git -cd jseql +git clone https://github.com/cipherstash/protectjs.git +cd protectjs ``` ### 2. Install Dependencies @@ -59,13 +59,13 @@ pnpm install ### 4. Build the Main Package -Before you can run any example apps, you need to build the `@cipherstash/jseql` package: +Before you can run any example apps, you need to build the `@cipherstash/protect` package: ```bash pnpm run build ``` -This command triggers Turborepo’s build pipeline, compiling the **jseql** package in `packages/jseql` and linking it locally so the example apps can reference it. +This command triggers Turborepo’s build pipeline, compiling the **@cipherstash/protect** package in `packages/protect` and linking it locally so the example apps can reference it. ### 5. Run an Example App @@ -77,7 +77,7 @@ pnpm run dev Navigate to one of the example apps in `apps/` and follow the instructions for the corresponding examples. -Now, you can view the running application (if it’s a web or server app) or otherwise test the example’s output. This will help confirm your local build of **jseql** is working correctly. +Now, you can view the running application (if it’s a web or server app) or otherwise test the example’s output. This will help confirm your local build of **@cipherstash/protect** is working correctly. ## Making Changes @@ -86,7 +86,7 @@ Now, you can view the running application (if it’s a web or server app) or oth git checkout -b feat/my-new-feature ``` -2. **Implement your changes** in the relevant package (most likely in `packages/jseql`). +2. **Implement your changes** in the relevant package (most likely in `packages/protect`). 3. **Write tests** to cover any new functionality or bug fixes. diff --git a/README.md b/README.md index 0e213e5b..9c3e9863 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -# jseql +# CipherStash Protect for JavaScript/TypeScript -[![Package Tests](https://github.com/cipherstash/jseql/actions/workflows/tests.yaml/badge.svg)](https://github.com/cipherstash/jseql/actions/workflows/tests.yaml) +[![Package Tests](https://github.com/cipherstash/protectjs/actions/workflows/tests.yaml/badge.svg)](https://github.com/cipherstash/protectjs/actions/workflows/tests.yaml) [![Built by CipherStash](https://raw.githubusercontent.com/cipherstash/meta/refs/heads/main/csbadge.svg)](https://cipherstash.com) -`jseql` is a JavaScript/TypeScript package for encrypting and decrypting data in PostgreSQL databases. +`@cipherstash/protect` is a JavaScript/TypeScript package for encrypting and decrypting data in PostgreSQL databases. Encryption operations happen directly in your app, and the ciphertext is stored in your PostgreSQL database. -Every value you encrypt with `jseql` has a unique key, made possible by CipherStash [ZeroKMS](https://cipherstash.com/products/zerokms)'s blazing fast bulk key operations. -Under the hood `jseql` uses CipherStash [Encrypt Query Language (EQL)](https://github.com/cipherstash/encrypt-query-language), and all ZeroKMS data keys are backed by a root key in [AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html). +Every value you encrypt with `@cipherstash/protect` has a unique key, made possible by CipherStash [ZeroKMS](https://cipherstash.com/products/zerokms)'s blazing fast bulk key operations. +Under the hood `@cipherstash/protect` uses CipherStash [Encrypt Query Language (EQL)](https://github.com/cipherstash/encrypt-query-language), and all ZeroKMS data keys are backed by a root key in [AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html). ## Table of Contents @@ -23,12 +23,12 @@ Under the hood `jseql` uses CipherStash [Encrypt Query Language (EQL)](https://g ## Features -`jseql` leverages [Encrypt Query Language (EQL)](https://github.com/cipherstash/encrypt-query-language) and [CipherStash](https://cipherstash.com) to encrypt data in a PostgreSQL database. +`@cipherstash/protect` is built on to protect data in a PostgreSQL database using industry standard encryption, and a key management service called [ZeroKMS](https://cipherstash.com/products/zerokms) that's built to work with data at scale. **Features:** -- **Bulk encryption and decryption**: `jseql` uses [ZeroKMS](https://cipherstash.com/products/zerokms) for encrypting and decrypting thousands of records at once, while using a unique key for every value. -- **Single item encryption and decryption**: Just looking for a way to encrypt and decrypt single values? `jseql` has you covered. -- **Really fast:** ZeroKMS's performance makes using millions of unique keys feasible and performant for real-world applications built with `jseql`. +- **Bulk encryption and decryption**: `@cipherstash/protect` uses [ZeroKMS](https://cipherstash.com/products/zerokms) for encrypting and decrypting thousands of records at once, while using a unique key for every value. +- **Single item encryption and decryption**: Just looking for a way to encrypt and decrypt single values? `@cipherstash/protect` has you covered. +- **Really fast:** ZeroKMS's performance makes using millions of unique keys feasible and performant for real-world applications built with `@cipherstash/protect`. - **Identity-aware encryption**: Lock down access to sensitive data by requiring a valid JWT to perform a decryption. - **TypeScript support**: Strongly typed with TypeScript interfaces and types. @@ -39,36 +39,20 @@ Under the hood `jseql` uses CipherStash [Encrypt Query Language (EQL)](https://g ## Installation -Install `jseql` via one of the following methods: +Install `@cipherstash/protect` via one of the following methods: ```bash -npm install @cipherstash/jseql +npm install @cipherstash/protect # or -yarn add @cipherstash/jseql +yarn add @cipherstash/protect # or -pnpm add @cipherstash/jseql +pnpm add @cipherstash/protect ``` -## Platform Support - -### Operating Systems - -| Linux | macOS | Windows | -| ------ | ----- | ------- | -| ✓ | ✓ | ✓ | - -### Node.js - -`jseql` actively supports all current and [maintenance releases of Node](https://github.com/nodejs/LTS#release-schedule). -If you're using a different version of Node and believe it should be supported, let us know. - -Older Node version support (minimum v10) may require lower Node-API versions. -See the Node [version support matrix](https://nodejs.org/api/n-api.html#node-api-version-matrix) for more details. - ### Bun (experimental) [Bun](https://bun.sh/) is an alternate JavaScript runtime that targets Node compatibility. -At the time of this writing, some Node-API functions are [not implemented](https://github.com/oven-sh/bun/issues/158) so `jseql` may not work with Bun. +At the time of this writing, some Node-API functions are [not implemented](https://github.com/oven-sh/bun/issues/158) so `@cipherstash/protect` may not work with Bun. ## Usage @@ -86,7 +70,7 @@ CS_CLIENT_ACCESS_KEY=your-client-access-key ``` > [!IMPORTANT] -> These values are required to use the `jseql` package. +> These values are required to use the `@cipherstash/protect` package. > The names of the variables must match the values above or the package will not work. #### client keys @@ -104,18 +88,18 @@ You can generate an access token in the dashboard or the CLI. ### Initialize the EQL client -Import the `eql` function from the `@cipherstash/jseql` package and initialize the EQL client with your CipherStash credentials. +Import the `protect` function from the `@cipherstash/protect` package and initialize a client with your CipherStash credentials. ```typescript -const { eql } = require('@cipherstash/jseql') -const eqlClient = await eql() +const { protect } = require('@cipherstash/protect') +const protectClient = await protect() ``` .. or using ES6? ```typescript -import { eql } from '@cipherstash/jseql' -const eqlClient = await eql() +import { protect } from '@cipherstash/protect' +const protectClient = await protect() ``` ### Encrypting data @@ -124,7 +108,7 @@ To encrypt data, use the `encrypt` function. This function takes a plaintext string and an object with the table and column name as parameters. ```typescript -const ciphertext = await eqlClient.encrypt('plaintext', { +const ciphertext = await protectClient.encrypt('plaintext', { column: 'column_name', table: 'users', }) @@ -144,7 +128,7 @@ To decrypt data, use the `decrypt` function. This function takes an encrypted data object and an object with the lock context as parameters. ```typescript -const plaintext = await eqlClient.decrypt(ciphertext) +const plaintext = await protectClient.decrypt(ciphertext) ``` The `decrypt` function returns a string with the plaintext data. @@ -155,13 +139,13 @@ The `decrypt` function returns a string with the plaintext data. > If you use a lock context to encrypt data, you must also use the same lock context to decrypt the data. > Otherwise, you will receive a `400` error from ZeroKMS indicating that the request was unable to generate a data key, and you will be unable to decrypt the data. -`jseql` supports lock contexts to ensure that only the intended users can access sensitive data. +`@cipherstash/protect` supports lock contexts to ensure that only the intended users can access sensitive data. To use a lock context, initialize a `LockContext` object with the identity claims. ```typescript -import { LockContext } from '@cipherstash/jseql/identify' +import { LockContext } from '@cipherstash/protect/identify' -// eqlClient from the previous steps +// protectClient from the previous steps const lc = new LockContext() ``` @@ -173,9 +157,9 @@ const lc = new LockContext() If you want to override the default context, you can pass a custom context to the `LockContext` constructor. ```typescript -import { LockContext } from '@cipherstash/jseql/identify' +import { LockContext } from '@cipherstash/protect/identify' -// eqlClient from the previous steps +// protectClient from the previous steps const lc = new LockContext({ context: { identityClaim: ['sub'], // this is the default context @@ -208,7 +192,7 @@ The `jwt_token_from_identiti_provider` is the JWT token from your identity provi ### Lock context with Next.js and Clerk -If you're using [Clerk](https://clerk.com/) as your identity provider, you can use the `jseqlClerkMiddleware` function to automatically set the CTS token for every user session. +If you're using [Clerk](https://clerk.com/) as your identity provider, you can use the `protectClerkMiddleware` function to automatically set the CTS token for every user session. Install the `@cipherstash/nextjs` package: @@ -224,10 +208,10 @@ In your `middleware.ts` file, add the following code: ```typescript import { clerkMiddleware } from '@clerk/nextjs/server' -import { jseqlClerkMiddleware } from '@cipherstash/nextjs/clerk' +import { protectClerkMiddleware } from '@cipherstash/nextjs/clerk' export default clerkMiddleware(async (auth, req: NextRequest) => { - return jseqlClerkMiddleware(auth, req) + return protectClerkMiddleware(auth, req) }) ``` @@ -264,7 +248,7 @@ export default async function Page() { Since the CTS token is already available, you can construct a `LockContext` object with the existing CTS token. ```typescript -import { LockContext } from '@cipherstash/jseql/identify' +import { LockContext } from '@cipherstash/protect/identify' import { getCtsToken } from '@cipherstash/nextjs' export default async function Page() { @@ -291,7 +275,7 @@ export default async function Page() { To encrypt data with a lock context, call the optional `withLockContext` method on the `encrypt` function and pass the lock context object as a parameter. ```typescript -const ciphertext = await eqlClient.encrypt('plaintext', { +const ciphertext = await protectClient.encrypt('plaintext', { table: 'users', column: 'email', }).withLockContext(lockContext) @@ -302,7 +286,7 @@ const ciphertext = await eqlClient.encrypt('plaintext', { To decrypt data with a lock context, call the optional `withLockContext` method on the `decrypt` function and pass the lock context object as a parameter. ```typescript -const plaintext = await eqlClient.decrypt(ciphertext).withLockContext(lockContext) +const plaintext = await protectClient.decrypt(ciphertext).withLockContext(lockContext) ``` ### Storing encrypted data in a database @@ -325,14 +309,14 @@ If you have a large list of items to encrypt or decrypt, you can use the **`bulk #### bulkEncrypt ```ts -const encryptedResults = await eqlClient.bulkEncrypt(plaintextsToEncrypt, { +const encryptedResults = await protectClient.bulkEncrypt(plaintextsToEncrypt, { column: 'email', table: 'Users', }) // or with lock context -const encryptedResults = await eqlClient.bulkEncrypt(plaintextsToEncrypt, { +const encryptedResults = await protectClient.bulkEncrypt(plaintextsToEncrypt, { column: 'email', table: 'Users', }).withLockContext(lockContext) @@ -407,11 +391,11 @@ if (encryptedResults) { #### bulkDecrypt ```ts -const decryptedResults = await eqlClient.bulkDecrypt(encryptedPayloads) +const decryptedResults = await protectClient.bulkDecrypt(encryptedPayloads) // or with lock context -const decryptedResults = await eqlClient.bulkDecrypt(encryptedPayloads).withLockContext(lockContext) +const decryptedResults = await protectClient.bulkDecrypt(encryptedPayloads).withLockContext(lockContext) ``` **Parameters** @@ -466,44 +450,44 @@ if (decryptedResults) { ## Supported data types -`jseql` currently supports encrypting and decrypting text. -Other data types like booleans, dates, ints, floats, and JSON are extremely well supported in other CipherStash products, and will be coming to `jseql`. -Until support for other data types are available in `jseql`, you can: +`@cipherstash/protect` currently supports encrypting and decrypting text. +Other data types like booleans, dates, ints, floats, and JSON are extremely well supported in other CipherStash products, and will be coming to `@cipherstash/protect`. +Until support for other data types are available in `@cipherstash/protect`, you can: - Read [about how these data types work in EQL](https://github.com/cipherstash/encrypt-query-language/blob/main/docs/reference/INDEX.md) -- Vote for this feature by adding a :+1: on this [GitHub Issue](https://github.com/cipherstash/jseql/issues/48). +- Vote for this feature by adding a :+1: on this [GitHub Issue](https://github.com/cipherstash/protectjs/issues/48). ## Searchable encryption -`jseql` does not currently support searching encrypted data. -Searchable encryption is an extremely well supported capability in other CipherStash products, and will be coming to `jseql`. -Until searchable encryption support is released in `jseql`, you can: +`@cipherstash/protect` does not currently support searching encrypted data. +Searchable encryption is an extremely well supported capability in other CipherStash products, and will be coming to `@cipherstash/protect`. +Until searchable encryption support is released in `@cipherstash/protect`, you can: - Read [about how searchable encryption works in EQL](https://github.com/cipherstash/encrypt-query-language) -- Vote for this feature by adding a :+1: on this [GitHub Issue](https://github.com/cipherstash/jseql/issues/46). +- Vote for this feature by adding a :+1: on this [GitHub Issue](https://github.com/cipherstash/protectjs/issues/46). ## Logging > [!IMPORTANT] -> `jseql` will NEVER log plaintext data. +> `@cipherstash/protect` will NEVER log plaintext data. > This is by design to prevent sensitive data from leaking into logs. -`@cipherstash/jseql` and `@cipherstash/nextjs` will log to the console with a log level of `info` by default. +`@cipherstash/protect` and `@cipherstash/nextjs` will log to the console with a log level of `info` by default. You can enable the logger by configuring the following environment variable: ```bash -JSEQL_LOG_LEVEL=debug # Enable debug logging -JSEQL_LOG_LEVEL=info # Enable info logging -JSEQL_LOG_LEVEL=error # Enable error logging +PROTECT_LOG_LEVEL=debug # Enable debug logging +PROTECT_LOG_LEVEL=info # Enable info logging +PROTECT_LOG_LEVEL=error # Enable error logging ``` ## Builds and bundling -`@cipherstash/jseql` is a native Node.js module, and relies on native Node.js `require` to load the package. +`@cipherstash/protect` is a native Node.js module, and relies on native Node.js `require` to load the package. ### Next.js -Using `@cipherstash/jseql` with Next.js? You need to opt-out from the Server Components bundling and use native Node.js `require` instead. +Using `@cipherstash/protect` with Next.js? You need to opt-out from the Server Components bundling and use native Node.js `require` instead. #### Using version 15 or later @@ -512,7 +496,7 @@ Using `@cipherstash/jseql` with Next.js? You need to opt-out from the Server Com ```js const nextConfig = { ... - serverExternalPackages: ['@cipherstash/jseql'], + serverExternalPackages: ['@cipherstash/protect'], } ``` @@ -524,7 +508,7 @@ const nextConfig = { const nextConfig = { ... experimental: { - serverComponentsExternalPackages: ['@cipherstash/jseql'], + serverComponentsExternalPackages: ['@cipherstash/protect'], }, } ``` @@ -533,15 +517,15 @@ const nextConfig = { - [Basic example](/apps/basic) - [Drizzle example](/apps/drizzle) -- [Next.js, Drizzle, and Clerk example](https://github.com/cipherstash/jseql-next-drizzle) +- [Next.js, Drizzle, and Clerk example](https://github.com/cipherstash/protectjs-next-drizzle) -`jseql` can be used with most ORMs that support PostgreSQL. -If you're interested in using `jseql` with a specific ORM, please [create an issue](https://github.com/cipherstash/jseql/issues/new). +`@cipherstash/protect` can be used with most ORMs that support PostgreSQL. +If you're interested in using `@cipherstash/protect` with a specific ORM, please [create an issue](https://github.com/cipherstash/protectjs/issues/new). ## CipherStash Client -`@cipherstash/jseql` is built on top of the CipherStash Client Rust SDK which is integrated with the `@cipherstash/jseql-ffi` package. -The `@cipherstash/jseql-ffi` package is [public on NPM](https://www.npmjs.com/package/@cipherstash/jseql-ffi), and the source code will be released on GitHub. +`@cipherstash/protect` is built on top of the CipherStash Client Rust SDK which is integrated with the `@cipherstash/jseql-ffi` package. +The `@cipherstash/jseql-ffi` package is [public on NPM](https://www.npmjs.com/package/@cipherstash/jseql-ffi), and the source code will be released on GitHub soon. The Cipherstash Client is configured by environment variables, which are used to initialize the client when the `eql` function is called: @@ -555,7 +539,7 @@ The Cipherstash Client is configured by environment variables, which are used to | `CS_CONFIG_PATH` | A temporary path to store the CipherStash client configuration. | No | `/home/{username}/.cipherstash` | > [!TIP] -> There are some configuration details you should take note of when deploying `jseql` in your production apps. +> There are some configuration details you should take note of when deploying `@cipherstash/protect` in your production apps. - If you've created a Workspace in a region other than `ap-southeast-2`, you will need to set the `CS_ZEROKMS_HOST` environment variable to the appropriate region. For example, if you are using ZeroKMS in the `eu-central-1` region, you need to set the `CS_ZEROKMS_HOST` variable to `https://eu-central-1.aws.viturhosted.net`. This is a known usability issue that will be addressed. - In most hosting environments, the `CS_CONFIG_PATH` environment variable will need to be set to a path that the user running the application has permission to write to. Setting `CS_CONFIG_PATH` to `/tmp/.cipherstash` will work in most cases, and has been tested on [Vercel](https://vercel.com/), [AWS Lambda](https://aws.amazon.com/lambda/), and other hosting environments. @@ -566,4 +550,4 @@ Please read the [contribution guide](CONTRIBUTE.md). ## License -`jseql` is [MIT licensed](./LICENSE.md). +`@cipherstash/protect` is [MIT licensed](./LICENSE.md). diff --git a/apps/basic/README.md b/apps/basic/README.md index b852ae5c..daa0bfdc 100644 --- a/apps/basic/README.md +++ b/apps/basic/README.md @@ -1,6 +1,6 @@ -# Basic example using @cipherstash/jseql +# Basic example using @cipherstash/protect -This is a basic example of how to use the @cipherstash/jseql package. +This is a basic example of how to use the @cipherstash/protect package. ## Usage @@ -11,8 +11,8 @@ CS_CLIENT_ID=your-client-id CS_CLIENT_KEY=your-client-key ``` -2. Run `npm install` to install the dependencies. +2. Run `pnpm install` to install the dependencies. -3. Run `npm start` to start the application. +3. Run `pnpm start` to start the application. 4. The application will log the plaintext to the console which has been encrypted using the CipherStash, decrypted, and logged the original plaintext. \ No newline at end of file diff --git a/apps/basic/index.mjs b/apps/basic/index.mjs index 5815cae6..d77da6c6 100644 --- a/apps/basic/index.mjs +++ b/apps/basic/index.mjs @@ -1,15 +1,15 @@ import 'dotenv/config' -import { eql } from '@cipherstash/jseql' +import { protect } from '@cipherstash/protect' async function main() { - const eqlClient = await eql() + const protectClient = await protect() - const ciphertext = await eqlClient.encrypt('plaintext', { + const ciphertext = await protectClient.encrypt('plaintext', { column: 'column_name', table: 'users', }) - const plaintext = await eqlClient.decrypt(ciphertext) + const plaintext = await protectClient.decrypt(ciphertext) console.log('The plaintext is:', plaintext) } diff --git a/apps/basic/package.json b/apps/basic/package.json index 5e055aab..556b1ed0 100644 --- a/apps/basic/package.json +++ b/apps/basic/package.json @@ -11,7 +11,7 @@ "license": "ISC", "description": "", "dependencies": { - "@cipherstash/jseql": "workspace:*", + "@cipherstash/protect": "workspace:*", "dotenv": "^16.4.7" } } diff --git a/apps/drizzle/drizzle.config.ts b/apps/drizzle/drizzle.config.ts index 6622da01..16835108 100644 --- a/apps/drizzle/drizzle.config.ts +++ b/apps/drizzle/drizzle.config.ts @@ -6,6 +6,6 @@ export default defineConfig({ schema: './src/db/schema.ts', dialect: 'postgresql', dbCredentials: { - url: process.env.DATABASE_URL!, + url: process.env.DATABASE_URL, }, }) diff --git a/apps/drizzle/drizzle/meta/0000_snapshot.json b/apps/drizzle/drizzle/meta/0000_snapshot.json index 03cadfab..1abd1658 100644 --- a/apps/drizzle/drizzle/meta/0000_snapshot.json +++ b/apps/drizzle/drizzle/meta/0000_snapshot.json @@ -34,9 +34,7 @@ "users_email_unique": { "name": "users_email_unique", "nullsNotDistinct": false, - "columns": [ - "email" - ] + "columns": ["email"] } } } @@ -49,4 +47,4 @@ "schemas": {}, "tables": {} } -} \ No newline at end of file +} diff --git a/apps/drizzle/drizzle/meta/_journal.json b/apps/drizzle/drizzle/meta/_journal.json index fc85947d..a9ab39cc 100644 --- a/apps/drizzle/drizzle/meta/_journal.json +++ b/apps/drizzle/drizzle/meta/_journal.json @@ -10,4 +10,4 @@ "breakpoints": true } ] -} \ No newline at end of file +} diff --git a/apps/drizzle/package.json b/apps/drizzle/package.json index 1debfcfc..f0e6eccc 100644 --- a/apps/drizzle/package.json +++ b/apps/drizzle/package.json @@ -20,7 +20,7 @@ "typescript": "^5.0.0" }, "dependencies": { - "@cipherstash/jseql": "workspace:*", + "@cipherstash/protect": "workspace:*", "drizzle-orm": "^0.33.0", "pg": "^8.13.1", "postgres": "^3.4.4" diff --git a/apps/drizzle/src/db/schema.ts b/apps/drizzle/src/db/schema.ts index cf33467a..4927b389 100644 --- a/apps/drizzle/src/db/schema.ts +++ b/apps/drizzle/src/db/schema.ts @@ -1,10 +1,10 @@ import 'dotenv/config' import { customType, + jsonb, pgTable, serial, varchar, - jsonb, } from 'drizzle-orm/pg-core' // Custom types will be implemented in the future - this is an example for now diff --git a/apps/drizzle/src/eql.ts b/apps/drizzle/src/eql.ts deleted file mode 100644 index 42838c2f..00000000 --- a/apps/drizzle/src/eql.ts +++ /dev/null @@ -1,4 +0,0 @@ -import 'dotenv/config' -import { eql } from '@cipherstash/jseql' - -export const eqlClient = await eql() diff --git a/apps/drizzle/src/insert.ts b/apps/drizzle/src/insert.ts index 14c59667..0c417c4a 100644 --- a/apps/drizzle/src/insert.ts +++ b/apps/drizzle/src/insert.ts @@ -3,7 +3,7 @@ import { parseArgs } from 'node:util' import { getTableName } from 'drizzle-orm' import { db } from './db' import { users } from './db/schema' -import { eqlClient } from './eql' +import { protectClient } from './protect' const getEmail = () => { const { values, positionals } = parseArgs({ @@ -26,7 +26,7 @@ if (!email) { throw new Error('Email is required') } -const encryptedEmail = await eqlClient.encrypt(email, { +const encryptedEmail = await protectClient.encrypt(email, { column: users.email_encrypted.name, table: getTableName(users), }) diff --git a/apps/drizzle/src/protect.ts b/apps/drizzle/src/protect.ts new file mode 100644 index 00000000..a992c4e9 --- /dev/null +++ b/apps/drizzle/src/protect.ts @@ -0,0 +1,4 @@ +import 'dotenv/config' +import { protect } from '@cipherstash/protect' + +export const protectClient = await protect() diff --git a/apps/drizzle/src/select.ts b/apps/drizzle/src/select.ts index 72a7fbf6..6a586b29 100644 --- a/apps/drizzle/src/select.ts +++ b/apps/drizzle/src/select.ts @@ -1,7 +1,7 @@ import 'dotenv/config' import { db } from './db' import { users } from './db/schema' -import { eqlClient } from './eql' +import { protectClient } from './protect' const sql = db .select({ @@ -15,7 +15,9 @@ console.log('[INFO] SQL statement:', sqlResult) const data = await sql.execute() const emails = await Promise.all( - data.map(async (row) => await eqlClient.decrypt(row.email as { c: string })), + data.map( + async (row) => await protectClient.decrypt(row.email as { c: string }), + ), ) console.log('[INFO] All emails have been decrypted by CipherStash Proxy') diff --git a/apps/hono-supabase/README.md b/apps/hono-supabase/README.md index 55c2ae70..3d6df371 100644 --- a/apps/hono-supabase/README.md +++ b/apps/hono-supabase/README.md @@ -1,6 +1,6 @@ # CipherStash JSEQL + Supabase + Hono Example -This project demonstrates how to encrypt data using [@cipherstash/jseql](https://www.npmjs.com/package/@cipherstash/jseql) before storing it in a [Supabase](https://supabase.com/) Postgres database. It uses [Hono](https://hono.dev/) to create a minimal RESTful API, showcasing how to seamlessly integrate field-level encryption into a typical web application workflow. +This project demonstrates how to encrypt data using [@cipherstash/protect](https://www.npmjs.com/package/@cipherstash/protect) before storing it in a [Supabase](https://supabase.com/) Postgres database. It uses [Hono](https://hono.dev/) to create a minimal RESTful API, showcasing how to seamlessly integrate field-level encryption into a typical web application workflow. ## Table of Contents - [Overview](#overview) @@ -23,7 +23,7 @@ This project demonstrates how to encrypt data using [@cipherstash/jseql](https:/ ## Overview **What does this example show?** -1. **Encrypting data** with [@cipherstash/jseql](https://www.npmjs.com/package/@cipherstash/jseql). +1. **Encrypting data** with [@cipherstash/protect](https://www.npmjs.com/package/@cipherstash/protect). 2. **Storing encrypted data** in a Postgres database (using Supabase). 3. **Retrieving and decrypting** that data in a minimal Hono-based REST API. @@ -53,8 +53,8 @@ This project demonstrates how to encrypt data using [@cipherstash/jseql](https:/ ### 1. Clone the repository ```bash -git clone https://github.com/cipherstash/jseql.git -cd jseql/apps/hono-supabase +git clone https://github.com/cipherstash/jsprotect.git +cd jsprotect/apps/hono-supabase ``` ### 2. Install dependencies @@ -167,12 +167,12 @@ import { createClient } from '@supabase/supabase-js' import { Hono } from 'hono' import { createRequire } from 'node:module' -// We use ES6 require for @cipherstash/jseql due to dynamic import limitations +// We use ES6 require for @cipherstash/protect due to dynamic import limitations const require = createRequire(import.meta.url) -const { eql } = require('@cipherstash/jseql') +const { protect } = require('@cipherstash/protect') // 1. Initialize the CipherStash EQL client using environment variables -const eqlClient = await eql() +const protectClient = await protect() // 2. Initialize Supabase client const supabaseUrl = process.env.SUPABASE_URL @@ -190,7 +190,7 @@ app.get('/users', async (c) => { if (users && users.length > 0) { const decryptedusers = await Promise.all( users.map(async (user) => { - const plaintextEmail = await eqlClient.decrypt(user.email) + const plaintextEmail = await protectClient.decrypt(user.email) return { ...user, email: plaintextEmail } }) ) @@ -200,7 +200,7 @@ app.get('/users', async (c) => { }) // 5. POST /users -// - Encrypts the `email` field using jseql +// - Encrypts the `email` field using jsprotect // - Inserts the encrypted data into the `users` table app.post('/users', async (c) => { const { email, name } = await c.req.json() @@ -209,7 +209,7 @@ app.post('/users', async (c) => { } // Encrypt the email - const encryptedEmail = await eqlClient.encrypt(email, { + const encryptedEmail = await protectClient.encrypt(email, { column: 'email', table: 'users', }) @@ -236,7 +236,7 @@ serve({ ``` **Key points to note:** -- `@cipherstash/jseql` provides two primary functions: `encrypt()` and `decrypt()`. +- `@cipherstash/protect` provides two primary functions: `encrypt()` and `decrypt()`. - The encrypted field is stored as JSON in the format `{ c: "ciphertext" }`. - `@hono/node-server` is used to run the Hono application as a Node.js server. - `dotenv/config` automatically loads environment variables from your `.env` file. @@ -246,6 +246,6 @@ serve({ ## Additional Resources -- [CipherStash JSEQL Documentation](https://github.com/cipherstash/jseql) +- [@cipherstash/protect Documentation](https://github.com/cipherstash/protectjs) - [Hono Framework](https://hono.dev/) - [Supabase Documentation](https://supabase.com/docs) \ No newline at end of file diff --git a/apps/hono-supabase/package.json b/apps/hono-supabase/package.json index 15895878..181a30be 100644 --- a/apps/hono-supabase/package.json +++ b/apps/hono-supabase/package.json @@ -6,7 +6,7 @@ "dev": "tsx watch src/index.ts" }, "dependencies": { - "@cipherstash/jseql": "workspace:*", + "@cipherstash/protect": "workspace:*", "@hono/node-server": "^1.13.7", "@supabase/supabase-js": "^2.47.10", "dotenv": "^16.4.7", diff --git a/apps/hono-supabase/tsconfig.json b/apps/hono-supabase/tsconfig.json index 7719c236..ad959210 100644 --- a/apps/hono-supabase/tsconfig.json +++ b/apps/hono-supabase/tsconfig.json @@ -5,10 +5,8 @@ "strict": true, "verbatimModuleSyntax": true, "skipLibCheck": true, - "types": [ - "node" - ], + "types": ["node"], "jsx": "react-jsx", - "jsxImportSource": "hono/jsx", + "jsxImportSource": "hono/jsx" } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 6b005f27..ce2fafae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "cipherstash", - "description": "Encrypted Query Language JavaScript/TypeScript Library", + "name": "@cipherstash/protectjs", + "description": "CipherStash Protect for JavaScript/TypeScript", "author": "CipherStash ", "keywords": [ "encrypted", @@ -11,11 +11,11 @@ "eql" ], "bugs": { - "url": "https://github.com/cipherstash/jseql/issues" + "url": "https://github.com/cipherstash/protectjs/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/cipherstash/jseql.git" + "url": "git+https://github.com/cipherstash/protectjs.git" }, "license": "MIT", "workspaces": [ diff --git a/packages/jseql/README.md b/packages/jseql/README.md index 7f07ec8c..6a65f652 100644 --- a/packages/jseql/README.md +++ b/packages/jseql/README.md @@ -1,4 +1,4 @@ # @cipherstash/jseql -This is the main package for the Encrypted Query Language (EQL) JavaScript/TypeScript library. -Please refer to the [main README](https://github.com/cipherstash/jseql) for more information. \ No newline at end of file +The `@cipherstash/jseql` package has been deprecated in favor of the `@cipherstash/protect` package. +Please refer to the [main README](https://github.com/cipherstash/protectjs) for more information. \ No newline at end of file diff --git a/packages/jseql/src/index.ts b/packages/jseql/src/index.ts deleted file mode 100644 index 423475b6..00000000 --- a/packages/jseql/src/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { EqlClient } from './ffi' - -export const eql = (): Promise => { - const client = new EqlClient() - return client.init() -} - -export type { EqlClient } from './ffi' -export * from './cs_plaintext_v1' -export * from './identify' -export * from './eql' diff --git a/packages/nextjs/README.md b/packages/nextjs/README.md new file mode 100644 index 00000000..4a26fb46 --- /dev/null +++ b/packages/nextjs/README.md @@ -0,0 +1,4 @@ +# @cipherstash/protect + +This is the main package for the CipherStash Protect JavaScript Package. +Please refer to the [main README](https://github.com/cipherstash/protectjs) for more information. \ No newline at end of file diff --git a/packages/nextjs/__tests__/nextjs.test.ts b/packages/nextjs/__tests__/nextjs.test.ts index cb745b32..584e393a 100644 --- a/packages/nextjs/__tests__/nextjs.test.ts +++ b/packages/nextjs/__tests__/nextjs.test.ts @@ -1,6 +1,6 @@ -// cts.test.ts -import { describe, it, expect, vi, afterEach } from 'vitest' import { type NextRequest, NextResponse } from 'next/server' +// cts.test.ts +import { afterEach, describe, expect, it, vi } from 'vitest' // --------------------------------------------- // 1) Mock next/headers before importing it @@ -48,11 +48,11 @@ vi.mock('../src/', async () => { import { cookies } from 'next/headers' import { logger } from '../../utils/logger' import { - getCtsToken, - resetCtsToken, - jseqlMiddleware, CS_COOKIE_NAME, type CtsToken, + getCtsToken, + jseqlMiddleware, + resetCtsToken, } from '../src/' describe('getCtsToken', () => { diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 7f732adc..c5c0761d 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -1,7 +1,7 @@ { "name": "@cipherstash/nextjs", "version": "1.2.0", - "description": "Nextjs middleware for jseql", + "description": "Nextjs package for use with @cipherstash/protect", "keywords": [ "encrypted", "typescript", @@ -9,11 +9,11 @@ "nextjs" ], "bugs": { - "url": "https://github.com/cipherstash/jseql/issues" + "url": "https://github.com/cipherstash/protectjs/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/cipherstash/jseql.git" + "url": "git+https://github.com/cipherstash/protectjs.git" }, "license": "MIT", "author": "CipherStash ", diff --git a/packages/nextjs/src/clerk/index.ts b/packages/nextjs/src/clerk/index.ts index 72b6f2a7..a48dfb53 100644 --- a/packages/nextjs/src/clerk/index.ts +++ b/packages/nextjs/src/clerk/index.ts @@ -1,11 +1,11 @@ import type { ClerkMiddlewareAuth } from '@clerk/nextjs/server' import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' -import { CS_COOKIE_NAME, resetCtsToken } from '../index' -import { setCtsToken } from '../cts' import { logger } from '../../../utils/logger' +import { setCtsToken } from '../cts' +import { CS_COOKIE_NAME, resetCtsToken } from '../index' -export const jseqlClerkMiddleware = async ( +export const protectClerkMiddleware = async ( auth: ClerkMiddlewareAuth, req: NextRequest, ) => { diff --git a/packages/nextjs/src/cts/index.ts b/packages/nextjs/src/cts/index.ts index 00b8ad77..85cad367 100644 --- a/packages/nextjs/src/cts/index.ts +++ b/packages/nextjs/src/cts/index.ts @@ -12,7 +12,7 @@ export const fetchCtsToken = async (oidcToken: string): GetCtsTokenResponse => { if (!workspaceId) { logger.error( - 'The "CS_WORKSPACE_ID" environment variable is not set, and is required by jseqlClerkMiddleware. No CipherStash session will be set.', + 'The "CS_WORKSPACE_ID" environment variable is not set, and is required by protectClerkMiddleware. No CipherStash session will be set.', ) return { diff --git a/packages/nextjs/src/index.ts b/packages/nextjs/src/index.ts index 88c7554a..9f552360 100644 --- a/packages/nextjs/src/index.ts +++ b/packages/nextjs/src/index.ts @@ -1,9 +1,9 @@ +import { decodeJwt } from 'jose' +import { cookies } from 'next/headers' import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' -import { cookies } from 'next/headers' -import { setCtsToken, fetchCtsToken } from './cts' import { logger } from '../../utils/logger' -import { decodeJwt } from 'jose' +import { fetchCtsToken, setCtsToken } from './cts' function getSubjectFromToken(jwt: string): string | undefined { const payload = decodeJwt(jwt) @@ -74,7 +74,7 @@ export const resetCtsToken = (res?: NextResponse) => { return response } -export const jseqlMiddleware = async ( +export const protectMiddleware = async ( oidcToken: string, req: NextRequest, res?: NextResponse, diff --git a/packages/jseql/CHANGELOG.md b/packages/protect/CHANGELOG.md similarity index 100% rename from packages/jseql/CHANGELOG.md rename to packages/protect/CHANGELOG.md diff --git a/packages/protect/README.md b/packages/protect/README.md new file mode 100644 index 00000000..4a26fb46 --- /dev/null +++ b/packages/protect/README.md @@ -0,0 +1,4 @@ +# @cipherstash/protect + +This is the main package for the CipherStash Protect JavaScript Package. +Please refer to the [main README](https://github.com/cipherstash/protectjs) for more information. \ No newline at end of file diff --git a/packages/jseql/__tests__/jseql.test.ts b/packages/protect/__tests__/jseql.test.ts similarity index 83% rename from packages/jseql/__tests__/jseql.test.ts rename to packages/protect/__tests__/jseql.test.ts index 304cd8df..a9f4dcab 100644 --- a/packages/jseql/__tests__/jseql.test.ts +++ b/packages/protect/__tests__/jseql.test.ts @@ -1,7 +1,7 @@ import 'dotenv/config' import { describe, expect, it } from 'vitest' -import { createEqlPayload, getPlaintext, eql, LockContext } from '../src' +import { LockContext, createEqlPayload, getPlaintext, protect } from '../src' import type { CsPlaintextV1Schema } from '../src/cs_plaintext_v1' describe('createEqlPayload', () => { @@ -120,27 +120,27 @@ describe('encryption and decryption', () => { }) it('should encrypt and decrypt a payload', async () => { - const eqlClient = await eql() + const protectClient = await protect() - const ciphertext = await eqlClient.encrypt('plaintext', { + const ciphertext = await protectClient.encrypt('plaintext', { column: 'column_name', table: 'users', }) - const plaintext = await eqlClient.decrypt(ciphertext) + const plaintext = await protectClient.decrypt(ciphertext) expect(plaintext).toEqual('plaintext') }, 30000) it('should return null if plaintext is null', async () => { - const eqlClient = await eql() + const protectClient = await protect() - const ciphertext = await eqlClient.encrypt(null, { + const ciphertext = await protectClient.encrypt(null, { column: 'column_name', table: 'users', }) - const plaintext = await eqlClient.decrypt(ciphertext) + const plaintext = await protectClient.decrypt(ciphertext) expect(plaintext).toEqual(null) }, 30000) @@ -148,8 +148,8 @@ describe('encryption and decryption', () => { describe('bulk encryption', () => { it('should bulk encrypt and decrypt a payload', async () => { - const eqlClient = await eql() - const ciphertexts = await eqlClient.bulkEncrypt( + const protectClient = await protect() + const ciphertexts = await protectClient.bulkEncrypt( [ { plaintext: 'test', @@ -166,7 +166,7 @@ describe('bulk encryption', () => { }, ) - const plaintexts = await eqlClient.bulkDecrypt(ciphertexts) + const plaintexts = await protectClient.bulkDecrypt(ciphertexts) expect(plaintexts).toEqual([ { @@ -181,8 +181,8 @@ describe('bulk encryption', () => { }, 30000) it('should return null if plaintexts is empty', async () => { - const eqlClient = await eql() - const ciphertexts = await eqlClient.bulkEncrypt([], { + const protectClient = await protect() + const ciphertexts = await protectClient.bulkEncrypt([], { table: 'users', column: 'column_name', }) @@ -190,9 +190,9 @@ describe('bulk encryption', () => { }, 30000) it('should return null if decrypting empty ciphertexts', async () => { - const eqlClient = await eql() + const protectClient = await protect() const ciphertexts = null - const plaintexts = await eqlClient.bulkDecrypt(ciphertexts) + const plaintexts = await protectClient.bulkDecrypt(ciphertexts) expect(plaintexts).toEqual(null) }, 30000) }) @@ -205,19 +205,19 @@ describe('bulk encryption', () => { // const userJwt = '' // describe('encryption and decryption with lock context', () => { // it('should encrypt and decrypt a payload with lock context', async () => { -// const eqlClient = await eql() +// const protectClient = await protect() // const lc = new LockContext() // const lockContext = await lc.identify(userJwt) -// const ciphertext = await eqlClient +// const ciphertext = await protectClient // .encrypt('plaintext', { // column: 'column_name', // table: 'users', // }) // .withLockContext(lockContext) -// const plaintext = await eqlClient +// const plaintext = await protectClient // .decrypt(ciphertext) // .withLockContext(lockContext) @@ -225,12 +225,12 @@ describe('bulk encryption', () => { // }, 30000) // it('should encrypt with context and be unable to decrypt without context', async () => { -// const eqlClient = await eql() +// const protectClient = await protect() // const lc = new LockContext() // const lockContext = await lc.identify(userJwt) -// const ciphertext = await eqlClient +// const ciphertext = await protectClient // .encrypt('plaintext', { // column: 'column_name', // table: 'users', @@ -238,7 +238,7 @@ describe('bulk encryption', () => { // .withLockContext(lockContext) // try { -// await eqlClient.decrypt(ciphertext) +// await protectClient.decrypt(ciphertext) // } catch (error) { // const e = error as Error // expect(e.message.startsWith('Failed to retrieve key')).toEqual(true) @@ -246,12 +246,12 @@ describe('bulk encryption', () => { // }, 30000) // it('should bulk encrypt and decrypt a payload with lock context', async () => { -// const eqlClient = await eql() +// const protectClient = await protect() // const lc = new LockContext() // const lockContext = await lc.identify(userJwt) -// const ciphertexts = await eqlClient +// const ciphertexts = await protectClient // .bulkEncrypt( // [ // { @@ -270,7 +270,7 @@ describe('bulk encryption', () => { // ) // .withLockContext(lockContext) -// const plaintexts = await eqlClient +// const plaintexts = await protectClient // .bulkDecrypt(ciphertexts) // .withLockContext(lockContext) diff --git a/packages/jseql/cs_plaintext_v1.schema.json b/packages/protect/cs_plaintext_v1.schema.json similarity index 82% rename from packages/jseql/cs_plaintext_v1.schema.json rename to packages/protect/cs_plaintext_v1.schema.json index de16fed7..56bec1b7 100644 --- a/packages/jseql/cs_plaintext_v1.schema.json +++ b/packages/protect/cs_plaintext_v1.schema.json @@ -27,10 +27,7 @@ "pattern": "^[a-zA-Z_]{1}[0-9a-zA-Z_]*$" } }, - "required": [ - "t", - "c" - ] + "required": ["t", "c"] }, "p": { "title": "plaintext", @@ -40,19 +37,8 @@ "title": "for query", "description": "Specifies that the plaintext should be encrypted for a specific query operation. If null, source encryption and encryption for all indexes will be performed.", "type": "string", - "enum": [ - "match", - "ore", - "unique", - "ste_vec", - "ejson_path" - ] + "enum": ["match", "ore", "unique", "ste_vec", "ejson_path"] } }, - "required": [ - "v", - "k", - "i", - "p" - ] -} \ No newline at end of file + "required": ["v", "k", "i", "p"] +} diff --git a/packages/jseql/generateSchema.mjs b/packages/protect/generateSchema.mjs similarity index 100% rename from packages/jseql/generateSchema.mjs rename to packages/protect/generateSchema.mjs diff --git a/packages/jseql/package.json b/packages/protect/package.json similarity index 83% rename from packages/jseql/package.json rename to packages/protect/package.json index 888d2b9d..8cb0d824 100644 --- a/packages/jseql/package.json +++ b/packages/protect/package.json @@ -1,21 +1,21 @@ { - "name": "@cipherstash/jseql", + "name": "@cipherstash/protect", "version": "4.0.0", - "description": "Encrypted Query Language JavaScript Library", + "description": "CipherStash Protech for JavaScript", "keywords": [ "encrypted", "query", "language", "typescript", "ts", - "eql" + "protect" ], "bugs": { - "url": "https://github.com/cipherstash/jseql/issues" + "url": "https://github.com/cipherstash/protectjs/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/cipherstash/jseql.git" + "url": "git+https://github.com/cipherstash/protectjs.git" }, "license": "MIT", "author": "CipherStash ", diff --git a/packages/jseql/src/cs_plaintext_v1.ts b/packages/protect/src/cs_plaintext_v1.ts similarity index 100% rename from packages/jseql/src/cs_plaintext_v1.ts rename to packages/protect/src/cs_plaintext_v1.ts diff --git a/packages/jseql/src/eql/index.ts b/packages/protect/src/eql/index.ts similarity index 100% rename from packages/jseql/src/eql/index.ts rename to packages/protect/src/eql/index.ts index 1feb7fbf..7b1834ee 100644 --- a/packages/jseql/src/eql/index.ts +++ b/packages/protect/src/eql/index.ts @@ -1,12 +1,12 @@ +import { logger } from '../../../utils/logger' import type { + Column, CsPlaintextV1Schema, ForQuery, + Plaintext, SchemaVersion, Table, - Column, - Plaintext, } from '../cs_plaintext_v1' -import { logger } from '../../../utils/logger' export type CreateEqlPayload = { plaintext: Plaintext diff --git a/packages/jseql/src/ffi/env-check.ts b/packages/protect/src/ffi/env-check.ts similarity index 100% rename from packages/jseql/src/ffi/env-check.ts rename to packages/protect/src/ffi/env-check.ts diff --git a/packages/jseql/src/ffi/index.ts b/packages/protect/src/ffi/index.ts similarity index 99% rename from packages/jseql/src/ffi/index.ts rename to packages/protect/src/ffi/index.ts index 5447f4d7..d64fcd05 100644 --- a/packages/jseql/src/ffi/index.ts +++ b/packages/protect/src/ffi/index.ts @@ -1,19 +1,19 @@ import { - newClient, - encrypt as ffiEncrypt, decrypt as ffiDecrypt, - encryptBulk as ffiEncryptBulk, decryptBulk as ffiDecryptBulk, + encrypt as ffiEncrypt, + encryptBulk as ffiEncryptBulk, + newClient, } from '@cipherstash/jseql-ffi' import { logger } from '../../../utils/logger' +import type { LockContext } from '../identify' import { checkEnvironmentVariables } from './env-check' import { - normalizeBulkEncryptPayloads, normalizeBulkDecryptPayloads, - normalizeBulkEncryptPayloadsWithLockContext, normalizeBulkDecryptPayloadsWithLockContext, + normalizeBulkEncryptPayloads, + normalizeBulkEncryptPayloadsWithLockContext, } from './payload-helpers' -import type { LockContext } from '../identify' // ------------------------ // Type Definitions @@ -544,7 +544,7 @@ class BulkDecryptOperationWithLockContext // ------------------------ // Main EQL Client // ------------------------ -export class EqlClient { +export class ProtectClient { private client: Client private workspaceId: string | undefined @@ -558,7 +558,7 @@ export class EqlClient { this.workspaceId = process.env.CS_WORKSPACE_ID } - async init(): Promise { + async init(): Promise { const c = await newClient() this.client = c return this diff --git a/packages/jseql/src/ffi/payload-helpers.ts b/packages/protect/src/ffi/payload-helpers.ts similarity index 100% rename from packages/jseql/src/ffi/payload-helpers.ts rename to packages/protect/src/ffi/payload-helpers.ts index 8be761c3..25bfe75b 100644 --- a/packages/jseql/src/ffi/payload-helpers.ts +++ b/packages/protect/src/ffi/payload-helpers.ts @@ -1,10 +1,10 @@ import type { - BulkEncryptPayload as InternalBulkEncryptPayload, BulkDecryptPayload as InternalBulkDecryptPayload, + BulkEncryptPayload as InternalBulkEncryptPayload, } from '@cipherstash/jseql-ffi' -import type { BulkEncryptPayload, BulkEncryptedData } from './index' import type { LockContext } from '../identify' +import type { BulkEncryptPayload, BulkEncryptedData } from './index' const getLockContextPayload = (lockContext: LockContext) => { const context = lockContext.getLockContext() diff --git a/packages/jseql/src/identify/index.ts b/packages/protect/src/identify/index.ts similarity index 100% rename from packages/jseql/src/identify/index.ts rename to packages/protect/src/identify/index.ts diff --git a/packages/protect/src/index.ts b/packages/protect/src/index.ts new file mode 100644 index 00000000..ede55123 --- /dev/null +++ b/packages/protect/src/index.ts @@ -0,0 +1,11 @@ +import { ProtectClient } from './ffi' + +export const protect = (): Promise => { + const client = new ProtectClient() + return client.init() +} + +export type { ProtectClient } from './ffi' +export * from './cs_plaintext_v1' +export * from './identify' +export * from './eql' diff --git a/packages/jseql/tsconfig.jest.json b/packages/protect/tsconfig.jest.json similarity index 100% rename from packages/jseql/tsconfig.jest.json rename to packages/protect/tsconfig.jest.json diff --git a/packages/jseql/tsconfig.json b/packages/protect/tsconfig.json similarity index 100% rename from packages/jseql/tsconfig.json rename to packages/protect/tsconfig.json diff --git a/packages/jseql/tsup.config.ts b/packages/protect/tsup.config.ts similarity index 100% rename from packages/jseql/tsup.config.ts rename to packages/protect/tsup.config.ts diff --git a/packages/utils/logger/index.ts b/packages/utils/logger/index.ts index 017d8e5f..99514a63 100644 --- a/packages/utils/logger/index.ts +++ b/packages/utils/logger/index.ts @@ -11,7 +11,7 @@ function getLevelValue(level: string): number { } } -const envLogLevel = process.env.JSEQL_LOG_LEVEL || 'info' +const envLogLevel = process.env.PROTECT_LOG_LEVEL || 'info' const currentLevel = getLevelValue(envLogLevel) function debug(...args: unknown[]): void { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 855fa461..3443a459 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,18 +26,18 @@ importers: apps/basic: dependencies: - '@cipherstash/jseql': + '@cipherstash/protect': specifier: workspace:* - version: link:../../packages/jseql + version: link:../../packages/protect dotenv: specifier: ^16.4.7 version: 16.4.7 apps/drizzle: dependencies: - '@cipherstash/jseql': + '@cipherstash/protect': specifier: workspace:* - version: link:../../packages/jseql + version: link:../../packages/protect drizzle-orm: specifier: ^0.33.0 version: 0.33.0(@types/pg@8.11.10)(pg@8.13.1)(postgres@3.4.5)(react@19.0.0) @@ -69,9 +69,9 @@ importers: apps/hono-supabase: dependencies: - '@cipherstash/jseql': + '@cipherstash/protect': specifier: workspace:* - version: link:../../packages/jseql + version: link:../../packages/protect '@hono/node-server': specifier: ^1.13.7 version: 1.13.7(hono@4.6.16) @@ -92,11 +92,14 @@ importers: specifier: ^4.7.1 version: 4.19.2 - packages/jseql: + packages/nextjs: dependencies: - '@cipherstash/jseql-ffi': - specifier: 0.5.0 - version: 0.5.0 + jose: + specifier: ^5.9.6 + version: 5.9.6 + next: + specifier: ^14 || ^15 + version: 15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) typescript: specifier: ^5.0.0 version: 5.7.2 @@ -105,15 +108,12 @@ importers: specifier: 4.24.0 version: 4.24.0 devDependencies: + '@clerk/nextjs': + specifier: ^6.9.7 + version: 6.9.7(next@15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) dotenv: specifier: ^16.4.7 version: 16.4.7 - execa: - specifier: ^9.5.2 - version: 9.5.2 - json-schema-to-typescript: - specifier: ^15.0.2 - version: 15.0.3 tsup: specifier: ^8.3.0 version: 8.3.5(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2) @@ -121,14 +121,11 @@ importers: specifier: ^2.1.8 version: 2.1.8(@types/node@22.10.5) - packages/nextjs: + packages/protect: dependencies: - jose: - specifier: ^5.9.6 - version: 5.9.6 - next: - specifier: ^14 || ^15 - version: 15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@cipherstash/jseql-ffi': + specifier: 0.5.0 + version: 0.5.0 typescript: specifier: ^5.0.0 version: 5.7.2 @@ -137,12 +134,15 @@ importers: specifier: 4.24.0 version: 4.24.0 devDependencies: - '@clerk/nextjs': - specifier: ^6.9.7 - version: 6.9.7(next@15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) dotenv: specifier: ^16.4.7 version: 16.4.7 + execa: + specifier: ^9.5.2 + version: 9.5.2 + json-schema-to-typescript: + specifier: ^15.0.2 + version: 15.0.3 tsup: specifier: ^8.3.0 version: 8.3.5(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2) From b506dece65ce9985516b87846315398d3b77ba08 Mon Sep 17 00:00:00 2001 From: CJ Brewer Date: Wed, 5 Feb 2025 14:37:52 -0700 Subject: [PATCH 2/2] fix(ci): protect tests --- .github/workflows/tests.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a3883e0e..399bb47a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -28,13 +28,13 @@ jobs: - name: Install dependencies run: pnpm install - - name: Create .env file in ./packages/jseql/ + - name: Create .env file in ./packages/protect/ run: | - touch ./packages/jseql/.env - echo "CS_WORKSPACE_ID=${{ secrets.CS_WORKSPACE_ID }}" >> ./packages/jseql/.env - echo "CS_CLIENT_ID=${{ secrets.CS_CLIENT_ID }}" >> ./packages/jseql/.env - echo "CS_CLIENT_KEY=${{ secrets.CS_CLIENT_KEY }}" >> ./packages/jseql/.env - echo "CS_CLIENT_ACCESS_KEY=${{ secrets.CS_CLIENT_ACCESS_KEY }}" >> ./packages/jseql/.env + touch ./packages/protect/.env + echo "CS_WORKSPACE_ID=${{ secrets.CS_WORKSPACE_ID }}" >> ./packages/protect/.env + echo "CS_CLIENT_ID=${{ secrets.CS_CLIENT_ID }}" >> ./packages/protect/.env + echo "CS_CLIENT_KEY=${{ secrets.CS_CLIENT_KEY }}" >> ./packages/protect/.env + echo "CS_CLIENT_ACCESS_KEY=${{ secrets.CS_CLIENT_ACCESS_KEY }}" >> ./packages/protect/.env # Run TurboRepo tests - name: Run tests