Skip to content

Commit

Permalink
feat: using the edge function
Browse files Browse the repository at this point in the history
  • Loading branch information
invisal committed Mar 19, 2024
1 parent ff347cf commit 13903bc
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 10 deletions.
7 changes: 4 additions & 3 deletions src/app/api/database/[database_id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NextResponse } from "next/server";
import { database } from "@/db/schema";
import { eq } from "drizzle-orm";
import { db } from "@/db";
import { encrypt } from "@/lib/encryption";
import { encrypt } from "@/lib/encryption-edge";
import { env } from "@/env";
import { SavedConnectionItemConfig } from "@/app/connect/saved-connection-storage";

Expand Down Expand Up @@ -65,7 +65,6 @@ export const PUT = withDatabaseOperation(
}

const data = parsed.data;
const key = Buffer.from(env.ENCRYPTION_KEY, "base64");

if (!permission.isOwner) {
return NextResponse.json({ error: "Unauthorization" }, { status: 500 });
Expand All @@ -78,7 +77,9 @@ export const PUT = withDatabaseOperation(
description: data.description,
name: data.name,
host: data.config.url,
token: data.config.token ? encrypt(key, data.config.token) : undefined,
token: data.config.token
? await encrypt(env.ENCRYPTION_KEY, data.config.token)
: undefined,
})
.where(eq(database.id, databaseInfo.id));

Expand Down
5 changes: 2 additions & 3 deletions src/app/api/ops/[database_id]/batch/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { env } from "@/env";
import { decrypt } from "@/lib/encryption";
import { decrypt } from "@/lib/encryption-edge";
import withDatabaseOperation from "@/lib/with-database-ops";
import { createClient } from "@libsql/client/web";
import { NextResponse } from "next/server";
Expand All @@ -21,9 +21,8 @@ export const POST = withDatabaseOperation<{
);
}

const key = Buffer.from(env.ENCRYPTION_KEY, "base64");
const url = database.host ?? "";
const token = decrypt(key, database.token ?? "");
const token = await decrypt(env.ENCRYPTION_KEY, database.token ?? "");

const client = createClient({
url,
Expand Down
5 changes: 2 additions & 3 deletions src/app/api/ops/[database_id]/query/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { env } from "@/env";
import { decrypt } from "@/lib/encryption";
import { decrypt } from "@/lib/encryption-edge";
import withDatabaseOperation from "@/lib/with-database-ops";
import { createClient } from "@libsql/client/web";
import { NextResponse } from "next/server";
Expand All @@ -19,9 +19,8 @@ export const POST = withDatabaseOperation<{
);
}

const key = Buffer.from(env.ENCRYPTION_KEY, "base64");
const url = database.host ?? "";
const token = decrypt(key, database.token ?? "");
const token = await decrypt(env.ENCRYPTION_KEY, database.token ?? "");

const client = createClient({
url,
Expand Down
1 change: 0 additions & 1 deletion src/env.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import "dotenv/config";
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

Expand Down
65 changes: 65 additions & 0 deletions src/lib/encryption-edge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const RANDOM_IV_LENGTH = 12;
const AUTH_TAG_SIZE = 16;

function base64ToArrayBuffer(base64: string) {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}

function arrayBufferToBase64(buffer: Uint8Array) {
let binary = "";
const bytes = new Uint8Array(buffer);
const len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}

export async function encrypt(keyInBase64: string, text: string) {
const iv = crypto.getRandomValues(new Uint8Array(RANDOM_IV_LENGTH));
const encoded = new TextEncoder().encode(text);
const keyBuffer = base64ToArrayBuffer(keyInBase64);

const key = await crypto.subtle.importKey(
"raw",
keyBuffer,
{ name: "AES-GCM" },
false,
["encrypt"]
);

const c = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv, tagLength: AUTH_TAG_SIZE * 8 },
key,
encoded
);

return arrayBufferToBase64(new Uint8Array([...iv, ...new Uint8Array(c)]));
}

export async function decrypt(keyInBase64: string, base64: string) {
const key = await crypto.subtle.importKey(
"raw",
base64ToArrayBuffer(keyInBase64),
{ name: "AES-GCM" },
false,
["decrypt"]
);

const e = base64ToArrayBuffer(base64);
const iv = e.slice(0, RANDOM_IV_LENGTH);
const content = e.slice(RANDOM_IV_LENGTH);

const c = await crypto.subtle.decrypt(
{ name: "AES-GCM", iv, tagLength: AUTH_TAG_SIZE * 8 },
key,
content
);

return new TextDecoder().decode(c);
}

0 comments on commit 13903bc

Please sign in to comment.