Skip to content

Commit f2f2e40

Browse files
authored
feat(experimental): Keypair auth (#494)
* reorganize helper file * wip * support keypair auth * fix unit tests * return error messages for keypair auth errors * Don't catch JsonWebToken errors * catch access token * move public keys to db * fix: add crud endpoints * wip * add algorithm * add feature envvar * handle each jwt type separately * rename * remove expiration limit
1 parent a6930af commit f2f2e40

File tree

27 files changed

+989
-194
lines changed

27 files changed

+989
-194
lines changed

.env.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
THIRDWEB_API_SECRET_KEY="test"
2+
POSTGRES_CONNECTION_URL="postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable"
3+
ADMIN_WALLET_ADDRESS="test"
4+
ENCRYPTION_PASSWORD="test"
5+
ENABLE_KEYPAIR_AUTH="true"

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"fastify": "^4.15.0",
6060
"fastify-plugin": "^4.5.0",
6161
"http-status-codes": "^2.2.0",
62+
"jsonwebtoken": "^9.0.2",
6263
"knex": "^3.1.0",
6364
"mnemonist": "^0.39.8",
6465
"node-cron": "^3.0.2",
@@ -77,6 +78,7 @@
7778
"@types/crypto-js": "^4.2.2",
7879
"@types/express": "^4.17.17",
7980
"@types/jest": "^29.5.11",
81+
"@types/jsonwebtoken": "^9.0.6",
8082
"@types/node": "^18.15.4",
8183
"@types/node-cron": "^3.0.8",
8284
"@types/pg": "^8.6.6",

src/db/keypair/delete.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Keypairs } from "@prisma/client";
2+
import { prisma } from "../client";
3+
4+
export const deleteKeypair = async ({
5+
hash,
6+
}: {
7+
hash: string;
8+
}): Promise<Keypairs> => {
9+
return prisma.keypairs.delete({
10+
where: { hash },
11+
});
12+
};

src/db/keypair/get.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Keypairs } from "@prisma/client";
2+
import { createHash } from "crypto";
3+
import { prisma } from "../client";
4+
5+
export const getKeypairByPublicKey = async ({
6+
publicKey,
7+
}: {
8+
publicKey: string;
9+
}): Promise<Keypairs | null> => {
10+
const hash = createHash("sha256").update(publicKey).digest("hex");
11+
12+
return prisma.keypairs.findUnique({
13+
where: { hash },
14+
});
15+
};

src/db/keypair/insert.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Keypairs } from "@prisma/client";
2+
import { createHash } from "crypto";
3+
import { KeypairAlgorithm } from "../../server/schemas/keypairs";
4+
import { prisma } from "../client";
5+
6+
export const insertKeypair = async ({
7+
publicKey,
8+
algorithm,
9+
label,
10+
}: {
11+
publicKey: string;
12+
algorithm: KeypairAlgorithm;
13+
label?: string;
14+
}): Promise<Keypairs> => {
15+
const hash = createHash("sha256").update(publicKey).digest("hex");
16+
17+
return prisma.keypairs.create({
18+
data: {
19+
hash,
20+
publicKey,
21+
algorithm,
22+
label,
23+
},
24+
});
25+
};

src/db/keypair/list.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { Keypairs } from "@prisma/client";
2+
import { prisma } from "../client";
3+
4+
export const listKeypairs = async (): Promise<Keypairs[]> => {
5+
return prisma.keypairs.findMany();
6+
};

src/db/tokens/getToken.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import { parseJWT } from "@thirdweb-dev/auth";
22
import { prisma } from "../client";
33

4-
interface GetTokenParams {
5-
jwt: string;
6-
}
7-
8-
export const getToken = async ({ jwt }: GetTokenParams) => {
4+
export const getToken = async (jwt: string) => {
95
const { payload } = parseJWT(jwt);
10-
return prisma.tokens.findUnique({
11-
where: {
12-
id: payload.jti,
13-
},
14-
});
6+
if (payload.jti) {
7+
return prisma.tokens.findUnique({
8+
where: {
9+
id: payload.jti,
10+
},
11+
});
12+
}
13+
return null;
1514
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- CreateTable
2+
CREATE TABLE "keypairs" (
3+
"hash" TEXT NOT NULL,
4+
"publicKey" TEXT NOT NULL,
5+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
6+
7+
CONSTRAINT "keypairs_pkey" PRIMARY KEY ("hash")
8+
);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
Warnings:
3+
4+
- Added the required column `algorithm` to the `keypairs` table without a default value. This is not possible if the table is not empty.
5+
6+
*/
7+
-- AlterTable
8+
ALTER TABLE "keypairs" ADD COLUMN "algorithm" TEXT NOT NULL;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- AlterTable
2+
ALTER TABLE "keypairs" ADD COLUMN "label" TEXT,
3+
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

src/prisma/schema.prisma

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,14 @@ model ChainIndexers {
265265
266266
@@map("chain_indexers")
267267
}
268+
269+
model Keypairs {
270+
hash String @id
271+
publicKey String
272+
algorithm String
273+
label String?
274+
createdAt DateTime @default(now())
275+
updatedAt DateTime @default(now())
276+
277+
@@map("keypairs")
278+
}

0 commit comments

Comments
 (0)