@better-auth/oauth-provider 1.6.12 → 1.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client-resource.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { S as handleMcpErrors, a as getOAuthProviderPlugin, i as getJwtPlugin } from "./utils-DoYEeMrg.mjs";
|
|
2
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
2
|
+
import { t as PACKAGE_VERSION } from "./version-CrTJknzp.mjs";
|
|
3
3
|
import { verifyAccessToken } from "better-auth/oauth2";
|
|
4
4
|
import { APIError } from "better-call";
|
|
5
5
|
import { logger } from "@better-auth/core/env";
|
package/dist/client.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { C as mcpHandler, _ as signedQueryIssuedAtParam, b as validateClientCredentials, c as isPKCERequired, d as parsePrompt, f as postLoginClearedParam, g as searchParamsToQuery, h as resolveSubjectIdentifier, i as getJwtPlugin, l as normalizeTimestampValue, m as resolveSessionAuthTime, n as decryptStoredClientSecret, o as getSignedQueryIssuedAt, p as removePromptFromQuery, r as getClient, s as getStoredToken, t as basicToClientCredentials, u as parseClientMetadata, v as storeClientSecret, x as verifyOAuthQueryParams, y as storeToken } from "./utils-DoYEeMrg.mjs";
|
|
2
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
2
|
+
import { t as PACKAGE_VERSION } from "./version-CrTJknzp.mjs";
|
|
3
3
|
import { APIError, createAuthEndpoint, createAuthMiddleware, getOAuthState, getSessionFromCtx, sessionMiddleware } from "better-auth/api";
|
|
4
4
|
import { generateCodeChallenge, getJwks, verifyJwsAccessToken } from "better-auth/oauth2";
|
|
5
5
|
import { APIError as APIError$1 } from "better-call";
|
|
@@ -14,6 +14,7 @@ import { mergeSchema } from "better-auth/db";
|
|
|
14
14
|
import * as z from "zod";
|
|
15
15
|
import { signJWT, toExpJWT } from "better-auth/plugins";
|
|
16
16
|
import { SignJWT, compactVerify, createLocalJWKSet, decodeJwt } from "jose";
|
|
17
|
+
import { SafeUrlSchema } from "@better-auth/core/utils/redirect-uri";
|
|
17
18
|
//#region src/consent.ts
|
|
18
19
|
async function consentEndpoint(ctx, opts) {
|
|
19
20
|
const oauthRequest = await oAuthState.get();
|
|
@@ -174,11 +175,6 @@ async function postLogin(ctx, opts) {
|
|
|
174
175
|
}
|
|
175
176
|
//#endregion
|
|
176
177
|
//#region src/types/zod.ts
|
|
177
|
-
const DANGEROUS_SCHEMES = [
|
|
178
|
-
"javascript:",
|
|
179
|
-
"data:",
|
|
180
|
-
"vbscript:"
|
|
181
|
-
];
|
|
182
178
|
/**
|
|
183
179
|
* Runtime schema for OAuthAuthorizationQuery.
|
|
184
180
|
* Uses passthrough to tolerate fields added by future extensions (PAR, FPA, etc.)
|
|
@@ -214,34 +210,6 @@ const verificationValueSchema = z.object({
|
|
|
214
210
|
referenceId: z.string().optional(),
|
|
215
211
|
authTime: z.number().optional()
|
|
216
212
|
}).passthrough();
|
|
217
|
-
/**
|
|
218
|
-
* Reusable URL validation for OAuth redirect URIs.
|
|
219
|
-
* - Blocks dangerous schemes (javascript:, data:, vbscript:)
|
|
220
|
-
* - For http/https: requires HTTPS (HTTP allowed only for loopback hosts: 127.0.0.0/8, [::1], *.localhost per RFC 6761)
|
|
221
|
-
* - Allows custom schemes for mobile apps (e.g., myapp://callback)
|
|
222
|
-
*/
|
|
223
|
-
const SafeUrlSchema = z.url().superRefine((val, ctx) => {
|
|
224
|
-
if (!URL.canParse(val)) {
|
|
225
|
-
ctx.addIssue({
|
|
226
|
-
code: "custom",
|
|
227
|
-
message: "URL must be parseable",
|
|
228
|
-
fatal: true
|
|
229
|
-
});
|
|
230
|
-
return z.NEVER;
|
|
231
|
-
}
|
|
232
|
-
const u = new URL(val);
|
|
233
|
-
if (DANGEROUS_SCHEMES.includes(u.protocol)) {
|
|
234
|
-
ctx.addIssue({
|
|
235
|
-
code: "custom",
|
|
236
|
-
message: "URL cannot use javascript:, data:, or vbscript: scheme"
|
|
237
|
-
});
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
if (u.protocol === "http:" && !isLoopbackHost(u.host)) ctx.addIssue({
|
|
241
|
-
code: "custom",
|
|
242
|
-
message: "Redirect URI must use HTTPS (HTTP allowed only for loopback hosts)"
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
213
|
//#endregion
|
|
246
214
|
//#region src/userinfo.ts
|
|
247
215
|
/**
|
|
@@ -1233,6 +1201,28 @@ const publicSessionMiddleware = (opts) => createAuthMiddleware(async (ctx) => {
|
|
|
1233
1201
|
if (!await verifyOAuthQueryParams(query, ctx.context.secret)) throw new APIError("UNAUTHORIZED", { error: "invalid_signature" });
|
|
1234
1202
|
});
|
|
1235
1203
|
//#endregion
|
|
1204
|
+
//#region src/oauthClient/privileges.ts
|
|
1205
|
+
/**
|
|
1206
|
+
* Authorizes a client action against the configured `clientPrivileges` hook.
|
|
1207
|
+
*
|
|
1208
|
+
* This is the single authorization helper for every OAuth client mutation. The
|
|
1209
|
+
* create path enforces it at the shared creation chokepoint so that no
|
|
1210
|
+
* registration route can reach client persistence without it.
|
|
1211
|
+
*
|
|
1212
|
+
* @throws APIError UNAUTHORIZED when there is no session or the hook denies the action.
|
|
1213
|
+
* @throws APIError BAD_REQUEST when the request carries no headers.
|
|
1214
|
+
*/
|
|
1215
|
+
async function assertClientPrivileges(ctx, session, opts, action) {
|
|
1216
|
+
if (!session) throw new APIError("UNAUTHORIZED");
|
|
1217
|
+
if (!ctx.headers) throw new APIError("BAD_REQUEST");
|
|
1218
|
+
if (opts.clientPrivileges && !await opts.clientPrivileges({
|
|
1219
|
+
headers: ctx.headers,
|
|
1220
|
+
action,
|
|
1221
|
+
session: session.session,
|
|
1222
|
+
user: session.user
|
|
1223
|
+
})) throw new APIError("UNAUTHORIZED");
|
|
1224
|
+
}
|
|
1225
|
+
//#endregion
|
|
1236
1226
|
//#region src/register.ts
|
|
1237
1227
|
/**
|
|
1238
1228
|
* Resolves the auth method and type for unauthenticated DCR.
|
|
@@ -1327,6 +1317,9 @@ async function checkOAuthClient(client, opts, settings) {
|
|
|
1327
1317
|
async function createOAuthClientEndpoint(ctx, opts, settings) {
|
|
1328
1318
|
const body = ctx.body;
|
|
1329
1319
|
const session = await getSessionFromCtx(ctx);
|
|
1320
|
+
if (settings.isRegister) {
|
|
1321
|
+
if (session) await assertClientPrivileges(ctx, session, opts, "create");
|
|
1322
|
+
} else await assertClientPrivileges(ctx, session, opts, "create");
|
|
1330
1323
|
const isPublic = body.token_endpoint_auth_method === "none";
|
|
1331
1324
|
await checkOAuthClient(ctx.body, opts, settings);
|
|
1332
1325
|
const clientId = opts.generateClientId?.() || generateRandomString(32, "a-z", "A-Z");
|
|
@@ -1658,16 +1651,6 @@ async function rotateClientSecretEndpoint(ctx, opts) {
|
|
|
1658
1651
|
clientSecret: (opts.prefix?.clientSecret ?? "") + clientSecret
|
|
1659
1652
|
});
|
|
1660
1653
|
}
|
|
1661
|
-
async function assertClientPrivileges(ctx, session, opts, action) {
|
|
1662
|
-
if (!session) throw new APIError("UNAUTHORIZED");
|
|
1663
|
-
if (!ctx.headers) throw new APIError("BAD_REQUEST");
|
|
1664
|
-
if (opts.clientPrivileges && !await opts.clientPrivileges({
|
|
1665
|
-
headers: ctx.headers,
|
|
1666
|
-
action,
|
|
1667
|
-
session: session.session,
|
|
1668
|
-
user: session.user
|
|
1669
|
-
})) throw new APIError("UNAUTHORIZED");
|
|
1670
|
-
}
|
|
1671
1654
|
//#endregion
|
|
1672
1655
|
//#region src/oauthClient/index.ts
|
|
1673
1656
|
const adminCreateOAuthClient = (opts) => createAuthEndpoint("/admin/oauth2/create-client", {
|
|
@@ -1850,7 +1833,6 @@ const adminCreateOAuthClient = (opts) => createAuthEndpoint("/admin/oauth2/creat
|
|
|
1850
1833
|
}
|
|
1851
1834
|
}
|
|
1852
1835
|
}, async (ctx) => {
|
|
1853
|
-
await assertClientPrivileges(ctx, await getSessionFromCtx(ctx), opts, "create");
|
|
1854
1836
|
return createOAuthClientEndpoint(ctx, opts, { isRegister: false });
|
|
1855
1837
|
});
|
|
1856
1838
|
const createOAuthClient = (opts) => createAuthEndpoint("/oauth2/create-client", {
|
|
@@ -2020,7 +2002,6 @@ const createOAuthClient = (opts) => createAuthEndpoint("/oauth2/create-client",
|
|
|
2020
2002
|
} }
|
|
2021
2003
|
} }
|
|
2022
2004
|
}, async (ctx) => {
|
|
2023
|
-
await assertClientPrivileges(ctx, await getSessionFromCtx(ctx), opts, "create");
|
|
2024
2005
|
return createOAuthClientEndpoint(ctx, opts, { isRegister: false });
|
|
2025
2006
|
});
|
|
2026
2007
|
const getOAuthClient = (opts) => createAuthEndpoint("/oauth2/get-client", {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/oauth-provider",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.14",
|
|
4
4
|
"description": "An oauth provider plugin for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,15 +64,15 @@
|
|
|
64
64
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
65
65
|
"listhen": "^1.9.0",
|
|
66
66
|
"tsdown": "0.21.1",
|
|
67
|
-
"@better-auth/core": "1.6.
|
|
68
|
-
"better-auth": "1.6.
|
|
67
|
+
"@better-auth/core": "1.6.14",
|
|
68
|
+
"better-auth": "1.6.14"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"@better-auth/utils": "0.4.1",
|
|
72
72
|
"@better-fetch/fetch": "1.1.21",
|
|
73
73
|
"better-call": "1.3.5",
|
|
74
|
-
"@better-auth/core": "^1.6.
|
|
75
|
-
"better-auth": "^1.6.
|
|
74
|
+
"@better-auth/core": "^1.6.14",
|
|
75
|
+
"better-auth": "^1.6.14"
|
|
76
76
|
},
|
|
77
77
|
"scripts": {
|
|
78
78
|
"build": "tsdown",
|