Skip to content

Commit 82302dc

Browse files
committed
add oidc provider
1 parent 65ee2e9 commit 82302dc

File tree

3 files changed

+495
-1
lines changed

3 files changed

+495
-1
lines changed

dev/oidc-provider.mjs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import Provider from "oidc-provider";
2+
3+
const ISSUER = "http://localhost:4000";
4+
const PORT = 4000;
5+
6+
// Simple in-memory account storage
7+
const accounts = {
8+
"test-user": {
9+
accountId: "test-user",
10+
11+
email_verified: true,
12+
name: "Test User",
13+
},
14+
};
15+
16+
// Configuration
17+
const configuration = {
18+
clients: [
19+
{
20+
client_id: "better-auth-dev",
21+
client_secret: "dev-secret-change-in-production",
22+
redirect_uris: ["http://localhost:3000/api/auth/callback/oidc"],
23+
response_types: ["code"],
24+
grant_types: ["authorization_code", "refresh_token"],
25+
token_endpoint_auth_method: "client_secret_post",
26+
},
27+
],
28+
cookies: {
29+
keys: ["some-secret-key-for-dev"],
30+
},
31+
findAccount: async (ctx, id) => {
32+
const account = accounts[id];
33+
if (!account) return undefined;
34+
35+
return {
36+
accountId: id,
37+
async claims() {
38+
return {
39+
sub: id,
40+
email: account.email,
41+
email_verified: account.email_verified,
42+
name: account.name,
43+
};
44+
},
45+
};
46+
},
47+
// Simple interaction - auto-login for dev
48+
interactions: {
49+
url(ctx, interaction) {
50+
return `/interaction/${interaction.uid}`;
51+
},
52+
},
53+
features: {
54+
devInteractions: { enabled: true }, // Enable dev interactions for easy testing
55+
refreshToken: { enabled: true },
56+
},
57+
ttl: {
58+
AccessToken: 3600, // 1 hour
59+
RefreshToken: 86400 * 30, // 30 days
60+
},
61+
};
62+
63+
const oidc = new Provider(ISSUER, configuration);
64+
65+
// Simple interaction endpoint for dev - auto-login as test-user
66+
oidc.use(async (ctx, next) => {
67+
if (ctx.path.startsWith("/interaction/")) {
68+
const uid = ctx.path.split("/")[2];
69+
const interaction = await oidc.interactionDetails(ctx.req, ctx.res);
70+
71+
if (interaction.prompt.name === "login") {
72+
// Auto-login as test-user for dev
73+
await oidc.interactionFinished(
74+
ctx.req,
75+
ctx.res,
76+
{
77+
login: {
78+
accountId: "test-user",
79+
},
80+
},
81+
{ mergeWithLastSubmission: false },
82+
);
83+
return;
84+
}
85+
86+
if (interaction.prompt.name === "consent") {
87+
// Auto-consent for dev
88+
const grant = new oidc.Grant({
89+
accountId: interaction.session.accountId,
90+
clientId: interaction.params.client_id,
91+
});
92+
93+
grant.addOIDCScope(
94+
interaction.params.scope
95+
?.split(" ")
96+
.filter((scope) => ["openid", "email", "profile"].includes(scope))
97+
.join(" ") || "openid email profile",
98+
);
99+
100+
await grant.save();
101+
102+
await oidc.interactionFinished(
103+
ctx.req,
104+
ctx.res,
105+
{
106+
consent: {
107+
grantId: grant.jti,
108+
},
109+
},
110+
{ mergeWithLastSubmission: true },
111+
);
112+
return;
113+
}
114+
}
115+
await next();
116+
});
117+
118+
oidc.listen(PORT, () => {
119+
console.log(`🔐 OIDC Provider running at ${ISSUER}`);
120+
console.log(`📝 Client ID: better-auth-dev`);
121+
console.log(`🔑 Client Secret: dev-secret-change-in-production`);
122+
console.log(`👤 Test user: [email protected]`);
123+
console.log(
124+
`\n⚙️ Update your .env.local with:\nOIDC_CLIENT_ID=better-auth-dev\nOIDC_CLIENT_SECRET=dev-secret-change-in-production\nOIDC_ISSUER_URL=${ISSUER}`,
125+
);
126+
});

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"format": "biome format --write",
1212
"test": "vitest",
1313
"type-check": "tsc --noEmit",
14-
"prepare": "husky"
14+
"prepare": "husky",
15+
"oidc": "node dev/oidc-provider.mjs"
1516
},
1617
"dependencies": {
1718
"better-auth": "1.4.0-beta.20",
@@ -32,6 +33,7 @@
3233
"husky": "^9.1.7",
3334
"jsdom": "^27.2.0",
3435
"lint-staged": "^16.0.0",
36+
"oidc-provider": "^9.5.2",
3537
"tailwindcss": "^4",
3638
"typescript": "^5",
3739
"vite-tsconfig-paths": "^5.1.4",

0 commit comments

Comments
 (0)