Skip to content

Commit 84ea6ea

Browse files
authored
Merge pull request #140 from cipherstash/mysql-example
feat: add mysql example
2 parents a335391 + 58df924 commit 84ea6ea

28 files changed

+1537
-31
lines changed

docs/concepts/searchable-encryption.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Searchable encryption
22

3-
Protect.js supports searching encrypted data, which enabled trusted data access so that you can:
3+
Protect.js supports searching encrypted data, which enables trusted data access so that you can:
44

55
1. Prove to your customers that you can track exactly what data is being accessed in your application.
66
2. Provide evidence for compliance requirements, such as [SOC 2](https://cipherstash.com/compliance/soc2) and [BDSG](https://cipherstash.com/compliance/bdsg).
@@ -69,20 +69,21 @@ CipherStash uses [EQL](https://github.com/cipherstash/encrypt-query-language) to
6969
// 1) Encrypt the search term
7070
const searchTerm = 'alice.johnson@example.com'
7171

72-
const encryptedParam = await protectClient.encrypt(searchTerm, {
72+
const encryptedParam = await protectClient.createSearchTerms([{
73+
value: searchTerm,
74+
table: protectedUsers, // Reference to the Protect table schema
7375
column: protectedUsers.email, // Your Protect column definition
74-
table: protectedUsers, // Reference to the table schema
75-
})
76+
}])
7677

7778
if (encryptedParam.failure) {
7879
// Handle the failure
7980
}
8081

81-
// 2) Build an equality query using EQL
82+
// 2) Build an equality query noting that EQL must be installed in order for the operation to work successfully
8283
const equalitySQL = `
8384
SELECT email
8485
FROM users
85-
WHERE cs_unique_v2($1) = cs_unique_v2($2)
86+
WHERE email = $1
8687
`
8788

8889
// 3) Execute the query, passing in the Postgres column name
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
DATABASE_URL=mysql://protect_example:password@127.0.0.1:3306/protect_example
2+
CS_CLIENT_ID=
3+
CS_CLIENT_KEY=
4+
CS_CLIENT_ACCESS_KEY=
5+
CS_WORKSPACE_CRN=
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Next.js + Drizzle ORM + MySQL + Protect.js Example
2+
3+
This example demonstrates how to build a modern web application using:
4+
- [Next.js](https://nextjs.org/) - React framework for production
5+
- [Drizzle ORM](https://orm.drizzle.team/) - TypeScript ORM for SQL databases
6+
- [MySQL](https://www.mysql.com/) - Popular open-source relational database
7+
- [Protect.js](https://cipherstash.com/protect) - Data protection and encryption library
8+
9+
## Features
10+
11+
- Full-stack TypeScript application
12+
- Database migrations and schema management with Drizzle
13+
- Data protection and encryption with Protect.js
14+
- Modern UI with Tailwind CSS
15+
- Form handling with React Hook Form and Zod validation
16+
- Docker-based MySQL database setup
17+
18+
## Prerequisites
19+
20+
- Node.js 18+
21+
- Docker and Docker Compose
22+
- MySQL (if running locally without Docker)
23+
24+
## Getting Started
25+
26+
1. Clone the repository and install dependencies:
27+
```bash
28+
npm install
29+
```
30+
31+
2. Set up your environment variables:
32+
Copy the `.env.example` file to `.env.local`:
33+
```bash
34+
cp .env.example .env.local
35+
```
36+
Then update the environment variables in `.env.local` with your Protect.js configuration values.
37+
38+
3. Start the MySQL database using Docker:
39+
```bash
40+
docker-compose up -d
41+
```
42+
43+
4. Run database migrations:
44+
```bash
45+
npm run db:generate
46+
npm run db:migrate
47+
```
48+
49+
5. Start the development server:
50+
```bash
51+
npm run dev
52+
```
53+
54+
The application will be available at `http://localhost:3000`.
55+
56+
## Project Structure
57+
58+
- `/src` - Application source code
59+
- `/drizzle` - Database migrations and schema
60+
- `/public` - Static assets
61+
- `drizzle.config.ts` - Drizzle ORM configuration
62+
- `docker-compose.yml` - Docker configuration for MySQL
63+
64+
## Available Scripts
65+
66+
- `npm run dev` - Start development server
67+
- `npm run build` - Build for production
68+
- `npm run start` - Start production server
69+
- `npm run db:generate` - Generate database migrations
70+
- `npm run db:migrate` - Run database migrations
71+
72+
## Learn More
73+
74+
- [Next.js Documentation](https://nextjs.org/docs)
75+
- [Drizzle ORM Documentation](https://orm.drizzle.team/docs/overview)
76+
- [Protect.js Documentation](https://cipherstash.com/protect/docs)
77+
- [MySQL Documentation](https://dev.mysql.com/doc/)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: '3.8'
2+
services:
3+
db:
4+
image: mysql:latest
5+
environment:
6+
MYSQL_ROOT_PASSWORD: password
7+
MYSQL_DATABASE: protect_example
8+
MYSQL_USER: protect_example
9+
MYSQL_PASSWORD: password
10+
ports:
11+
- "3306:3306"
12+
volumes:
13+
- mysql_data:/var/lib/mysql
14+
15+
volumes:
16+
mysql_data:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'dotenv/config'
2+
import { defineConfig } from 'drizzle-kit'
3+
export default defineConfig({
4+
dialect: 'mysql',
5+
schema: './src/db/schema.ts',
6+
dbCredentials: {
7+
host: '127.0.0.1',
8+
port: 3306,
9+
user: 'protect_example',
10+
password: 'password',
11+
database: 'protect_example',
12+
},
13+
})
14+
15+
// mysql://protect_example:password@127.0.0.1:3306/protect_example
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CREATE TABLE `users` (
2+
`id` int AUTO_INCREMENT NOT NULL,
3+
`name` json,
4+
`email` json,
5+
CONSTRAINT `users_id` PRIMARY KEY(`id`)
6+
);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"version": "5",
3+
"dialect": "mysql",
4+
"id": "03335511-a5f1-45e4-bcf7-227e326b28a5",
5+
"prevId": "00000000-0000-0000-0000-000000000000",
6+
"tables": {
7+
"users": {
8+
"name": "users",
9+
"columns": {
10+
"id": {
11+
"name": "id",
12+
"type": "int",
13+
"primaryKey": false,
14+
"notNull": true,
15+
"autoincrement": true
16+
},
17+
"name": {
18+
"name": "name",
19+
"type": "json",
20+
"primaryKey": false,
21+
"notNull": false,
22+
"autoincrement": false
23+
},
24+
"email": {
25+
"name": "email",
26+
"type": "json",
27+
"primaryKey": false,
28+
"notNull": false,
29+
"autoincrement": false
30+
}
31+
},
32+
"indexes": {},
33+
"foreignKeys": {},
34+
"compositePrimaryKeys": {
35+
"users_id": {
36+
"name": "users_id",
37+
"columns": [
38+
"id"
39+
]
40+
}
41+
},
42+
"uniqueConstraints": {},
43+
"checkConstraint": {}
44+
}
45+
},
46+
"views": {},
47+
"_meta": {
48+
"schemas": {},
49+
"tables": {},
50+
"columns": {}
51+
},
52+
"internal": {
53+
"tables": {},
54+
"indexes": {}
55+
}
56+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"version": "7",
3+
"dialect": "mysql",
4+
"entries": [
5+
{
6+
"idx": 0,
7+
"version": "5",
8+
"when": 1748545269720,
9+
"tag": "0000_brave_madrox",
10+
"breakpoints": true
11+
}
12+
]
13+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { NextConfig } from 'next'
2+
3+
const nextConfig: NextConfig = {
4+
serverExternalPackages: ['@cipherstash/protect', 'mysql2'],
5+
}
6+
7+
export default nextConfig
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "next-drizzle-mysql",
3+
"version": "0.1.0",
4+
"private": true,
5+
"scripts": {
6+
"dev": "next dev --turbopack",
7+
"build": "next build",
8+
"start": "next start",
9+
"db:generate": "drizzle-kit generate",
10+
"db:migrate": "drizzle-kit migrate"
11+
},
12+
"dependencies": {
13+
"@cipherstash/protect": "^8.3.0",
14+
"@hookform/resolvers": "^5.0.1",
15+
"drizzle-orm": "^0.44.0",
16+
"mysql2": "^3.14.1",
17+
"next": "15.3.2",
18+
"react": "^19.0.0",
19+
"react-dom": "^19.0.0",
20+
"react-hook-form": "^7.56.4",
21+
"zod": "^3.24.2"
22+
},
23+
"devDependencies": {
24+
"@tailwindcss/postcss": "^4",
25+
"@types/node": "^20",
26+
"@types/react": "^19",
27+
"@types/react-dom": "^19",
28+
"dotenv": "^16.4.7",
29+
"drizzle-kit": "^0.30.5",
30+
"tailwindcss": "^4",
31+
"typescript": "^5"
32+
}
33+
}

0 commit comments

Comments
 (0)