Skip to content

Commit

Permalink
Merge pull request #8 from cipherstash/plaintext-schema
Browse files Browse the repository at this point in the history
feat(jseql): implement eql plaintest schema
  • Loading branch information
calvinbrewer authored Nov 20, 2024
2 parents 637e0e2 + e02edaf commit 78df8a9
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 123 deletions.
5 changes: 5 additions & 0 deletions .changeset/lemon-bananas-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cipherstash/jseql": minor
---

Implemented new CsPlaintextV1Schema type and schema.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ bun add @cipherstash/jseql
import {
createEqlPayload,
getPlaintext,
type CsEncryptedV1Schema,
type CsPlaintextV1Schema,
} from '@cipherstash/jseql'
```

Expand Down Expand Up @@ -92,7 +92,7 @@ Extracts the plaintext data from an EQL payload.

**Parameters:**

- `payload` (`CsEncryptedV1Schema` | null): The EQL payload.
- `payload` (`CsPlaintextV1Schema` | null): The EQL payload.

**Returns:**

Expand Down
Binary file modified bun.lockb
Binary file not shown.
58 changes: 58 additions & 0 deletions packages/jseql/cs_plaintext_v1.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "The EQL plaintext JSON payload sent by a client (such as an application) to CipherStash Proxy.",
"type": "object",
"properties": {
"v": {
"title": "Schema version",
"type": "integer"
},
"k": {
"title": "kind",
"type": "string",
"const": "pt"
},
"i": {
"title": "ident",
"type": "object",
"properties": {
"t": {
"title": "table",
"type": "string",
"pattern": "^[a-zA-Z_]{1}[0-9a-zA-Z_]*$"
},
"c": {
"title": "column",
"type": "string",
"pattern": "^[a-zA-Z_]{1}[0-9a-zA-Z_]*$"
}
},
"required": [
"t",
"c"
]
},
"p": {
"title": "plaintext",
"type": "string"
},
"q": {
"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"
]
}
},
"required": [
"v",
"k",
"i",
"p"
]
}
14 changes: 14 additions & 0 deletions packages/jseql/generateSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bun
import { $ } from 'bun'

const url =
'https://raw.githubusercontent.com/cipherstash/encrypt-query-language/main/sql/schemas/cs_plaintext_v1.schema.json'
const response = await fetch(url)
const data = await response.json()

console.log(JSON.stringify(data, null, 2))
await Bun.write('./cs_plaintext_v1.schema.json', JSON.stringify(data, null, 2))

await $`bun run generate-types`

console.log('Types generated!')
2 changes: 1 addition & 1 deletion packages/jseql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"generate-types": "json2ts ../../../cs_encrypted_v1.schema.json --output ./cs_encrypted_v1.ts",
"generate-types": "json2ts ./cs_plaintext_v1.schema.json --output ./src/cs_plaintext_v1.ts",
"test": "bun test tests"
},
"devDependencies": {
Expand Down
57 changes: 0 additions & 57 deletions packages/jseql/src/cs_encrypted_v1.ts

This file was deleted.

33 changes: 33 additions & 0 deletions packages/jseql/src/cs_plaintext_v1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/

export type SchemaVersion = number
export type Kind = 'pt'
export type Table = string
export type Column = string
export type Plaintext = string
/**
* Specifies that the plaintext should be encrypted for a specific query operation. If null, source encryption and encryption for all indexes will be performed.
*/
export type ForQuery = 'match' | 'ore' | 'unique' | 'ste_vec' | 'ejson_path'

/**
* The EQL plaintext JSON payload sent by a client (such as an application) to CipherStash Proxy.
*/
export interface CsPlaintextV1Schema {
v: SchemaVersion
k: Kind
i: Ident
p: Plaintext
q?: ForQuery
[k: string]: unknown
}
export interface Ident {
t: Table
c: Column
[k: string]: unknown
}
61 changes: 40 additions & 21 deletions packages/jseql/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,68 @@
export * from './cs_encrypted_v1'
import type { CsEncryptedV1Schema } from './cs_encrypted_v1'
export * from './cs_plaintext_v1'
import type {
CsPlaintextV1Schema,
ForQuery,
SchemaVersion,
Kind,
Table,
Column,
Plaintext,
} from './cs_plaintext_v1'
import { getLogger } from '@logtape/logtape'

const logger = getLogger(['jseql'])

type CreateEqlPayload = {
plaintext: string | undefined
table: string
column: string
version?: number
schemaVersion?: number
queryType?: string | null
export type CreateEqlPayload = {
plaintext: Plaintext
table: Table
column: Column
schemaVersion?: SchemaVersion
queryType?: ForQuery | null
}

export type Result = {
failure?: boolean
error?: Error
plaintext?: Plaintext
}

export const createEqlPayload = ({
plaintext,
table,
column,
version = 1,
schemaVersion = 1,
queryType = null,
}: CreateEqlPayload): CsEncryptedV1Schema => {
const payload: CsEncryptedV1Schema = {
v: version,
s: 1,
}: CreateEqlPayload): CsPlaintextV1Schema => {
const payload: CsPlaintextV1Schema = {
v: schemaVersion,
k: 'pt',
p: plaintext ?? '',
i: {
t: table,
c: column,
},
q: queryType,
}

if (queryType) {
payload.q = queryType
}

logger.debug('Creating the EQL payload', payload)
return payload
}

export const getPlaintext = (
payload: CsEncryptedV1Schema | null,
): string | undefined => {
if (payload?.k === 'pt') {
export const getPlaintext = (payload: CsPlaintextV1Schema): Result => {
if (payload?.p && payload?.k === 'pt') {
logger.debug('Returning the plaintext data from the EQL payload', payload)
return payload.p
return {
failure: false,
plaintext: payload.p,
}
}

logger.error('No plaintext data found in the EQL payload', payload ?? {})
return undefined
return {
failure: true,
error: new Error('No plaintext data found in the EQL payload'),
}
}
Loading

0 comments on commit 78df8a9

Please sign in to comment.