Skip to content

Commit 1c7092c

Browse files
authored
feat: Add OIDC Salt service (#64)
* Add salt endpoint * Verify JWT * Add hash salt * Add hash salt * Update packages/auth-server/server/api/salt.ts * Lint * lint * Remove axios * Remove axios * Make SALT_ENTROPY required * Use jose * Encode data in buffer * Crop salt
1 parent 702d01c commit 1c7092c

File tree

5 files changed

+574
-3455
lines changed

5 files changed

+574
-3455
lines changed

packages/auth-server/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SALT_ENTROPY=
2+
APP_AUD=

packages/auth-server/nuxt.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default defineNuxtConfig({
2727
],
2828
},
2929
},
30-
ssr: false,
30+
ssr: true,
3131
devServer: {
3232
port: 3002,
3333
},

packages/auth-server/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@vueuse/nuxt": "^11.1.0",
2121
"@wagmi/core": "^2.13.3",
2222
"@wagmi/vue": "^0.0.49",
23+
"jose": "^5.9.6",
2324
"date-fns": "^4.1.0",
2425
"nuxt": "^3.12.3",
2526
"nuxt-gtag": "3.0.2",
@@ -42,4 +43,4 @@
4243
"overrides": {
4344
"vue": "latest"
4445
}
45-
}
46+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import crypto from "crypto";
2+
import { defineEventHandler, getHeader } from "h3";
3+
import * as jose from 'jose';
4+
5+
const GOOGLE_JWKS_URL = new URL("https://www.googleapis.com/oauth2/v3/certs");
6+
const GOOGLE_ISSUER = "https://accounts.google.com";
7+
8+
const APP_AUD = process.env.APP_AUD;
9+
if (!APP_AUD) {
10+
throw new Error("APP_AUD environment variable is required but not set");
11+
}
12+
13+
const SALT_ENTROPY = process.env.SALT_ENTROPY;
14+
if (!SALT_ENTROPY) {
15+
throw new Error("SALT_ENTROPY environment variable is required but not set");
16+
}
17+
18+
19+
export default defineEventHandler(async (event) => {
20+
const authHeader = getHeader(event, "Authorization");
21+
22+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
23+
throw createError({
24+
statusCode: 401,
25+
message: "Unauthorized - Missing or invalid token",
26+
});
27+
}
28+
29+
const jwt = authHeader.split(" ")[1];
30+
31+
try {
32+
const JWKS = jose.createRemoteJWKSet(GOOGLE_JWKS_URL)
33+
34+
const { payload } = await jose.jwtVerify(jwt, JWKS, {
35+
issuer: GOOGLE_ISSUER,
36+
audience: APP_AUD,
37+
});
38+
39+
const iss = payload.iss;
40+
const aud = payload.aud;
41+
const sub = payload.sub;
42+
43+
const data = Buffer.from(`${iss}${aud}${sub}${SALT_ENTROPY}`, "ascii");
44+
const hash = crypto.createHash("sha256").update(data).digest("hex").slice(0, 62);
45+
46+
return { salt: hash };
47+
} catch {
48+
throw createError({
49+
statusCode: 401,
50+
message: "Unauthorized - Invalid token",
51+
});
52+
}
53+
});

0 commit comments

Comments
 (0)