@codefox-inc/oauth-provider 0.4.1 → 0.4.2
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/README.md +28 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -1
- package/dist/client/index.js.map +1 -1
- package/dist/component/clientManagement.d.ts.map +1 -1
- package/dist/component/clientManagement.js +9 -0
- package/dist/component/clientManagement.js.map +1 -1
- package/dist/component/handlers.d.ts +19 -1
- package/dist/component/handlers.d.ts.map +1 -1
- package/dist/component/handlers.js +76 -15
- package/dist/component/handlers.js.map +1 -1
- package/dist/component/mutations.d.ts +3 -1
- package/dist/component/mutations.d.ts.map +1 -1
- package/dist/component/mutations.js +113 -19
- package/dist/component/mutations.js.map +1 -1
- package/dist/component/queries.d.ts +7 -1
- package/dist/component/queries.d.ts.map +1 -1
- package/dist/component/queries.js +7 -1
- package/dist/component/queries.js.map +1 -1
- package/dist/component/schema.d.ts +7 -1
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +3 -0
- package/dist/component/schema.js.map +1 -1
- package/dist/lib/oauth.d.ts.map +1 -1
- package/dist/lib/oauth.js +26 -8
- package/dist/lib/oauth.js.map +1 -1
- package/package.json +1 -1
- package/src/client/__tests__/oauth-provider.test.ts +15 -0
- package/src/client/index.ts +6 -1
- package/src/component/__tests__/bugs.test.ts +1001 -0
- package/src/component/__tests__/handlers-protocol.test.ts +148 -0
- package/src/component/__tests__/oauth.test.ts +18 -15
- package/src/component/__tests__/rfc-compliance.test.ts +233 -0
- package/src/component/clientManagement.ts +11 -0
- package/src/component/handlers.ts +116 -18
- package/src/component/mutations.ts +159 -17
- package/src/component/queries.ts +6 -1
- package/src/component/schema.ts +3 -0
- package/src/lib/__tests__/oauth-jwt.test.ts +1 -1
- package/src/lib/oauth.ts +28 -8
package/src/lib/oauth.ts
CHANGED
|
@@ -135,6 +135,8 @@ export async function getJWKS(config: OAuthConfig): Promise<{ keys: JoseJWK[] }>
|
|
|
135
135
|
return {
|
|
136
136
|
...publicKey,
|
|
137
137
|
kid: publicKey.kid ?? keyId,
|
|
138
|
+
use: publicKey.use ?? "sig",
|
|
139
|
+
alg: publicKey.alg ?? "RS256",
|
|
138
140
|
};
|
|
139
141
|
});
|
|
140
142
|
|
|
@@ -145,13 +147,29 @@ function ensureKidOnJwksKeys(keys: JoseJWK[], keyId: string): JoseJWK[] {
|
|
|
145
147
|
return keys.map((key) => ({
|
|
146
148
|
...key,
|
|
147
149
|
kid: key.kid ?? keyId,
|
|
150
|
+
use: key.use ?? "sig",
|
|
151
|
+
alg: key.alg ?? "RS256",
|
|
148
152
|
}));
|
|
149
153
|
}
|
|
150
154
|
|
|
151
155
|
export function getSigningKeyId(config: OAuthConfig): string {
|
|
152
|
-
|
|
156
|
+
let jwks: { keys?: JoseJWK[] };
|
|
157
|
+
try {
|
|
158
|
+
jwks = JSON.parse(config.jwks) as { keys?: JoseJWK[] };
|
|
159
|
+
} catch {
|
|
160
|
+
return config.keyId ?? DEFAULT_KEY_ID;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (config.keyId) {
|
|
164
|
+
const hasExplicitKids = jwks.keys?.some((key) => typeof key.kid === "string" && key.kid.length > 0) ?? false;
|
|
165
|
+
const publishesKeyId = jwks.keys?.some((key) => key.kid === config.keyId) ?? false;
|
|
166
|
+
if (hasExplicitKids && !publishesKeyId) {
|
|
167
|
+
throw new Error(`Configured keyId "${config.keyId}" is not present in JWKS`);
|
|
168
|
+
}
|
|
169
|
+
return config.keyId;
|
|
170
|
+
}
|
|
171
|
+
|
|
153
172
|
try {
|
|
154
|
-
const jwks = JSON.parse(config.jwks) as { keys?: JoseJWK[] };
|
|
155
173
|
const kid = jwks.keys?.[0]?.kid;
|
|
156
174
|
if (typeof kid === "string" && kid.length > 0) {
|
|
157
175
|
return kid;
|
|
@@ -223,16 +241,18 @@ export async function verifyAccessToken(
|
|
|
223
241
|
async function getVerificationKey(
|
|
224
242
|
config: OAuthConfig
|
|
225
243
|
): Promise<ReturnType<typeof createLocalJWKSet>> {
|
|
226
|
-
const
|
|
244
|
+
const keyId = getSigningKeyId(config);
|
|
245
|
+
const cacheKey = `${config.jwks}:${keyId}`;
|
|
246
|
+
const cached = jwksKeyCache.get(cacheKey);
|
|
227
247
|
if (cached) return cached;
|
|
228
248
|
|
|
229
249
|
const jwks = JSON.parse(config.jwks) as { keys: JoseJWK[] };
|
|
230
250
|
if (!jwks.keys?.length) {
|
|
231
251
|
throw new Error("jwks must include at least one key");
|
|
232
252
|
}
|
|
233
|
-
const normalized = { keys: ensureKidOnJwksKeys(jwks.keys,
|
|
253
|
+
const normalized = { keys: ensureKidOnJwksKeys(jwks.keys, keyId) };
|
|
234
254
|
const localJwks = createLocalJWKSet(normalized);
|
|
235
|
-
jwksKeyCache.set(
|
|
255
|
+
jwksKeyCache.set(cacheKey, localJwks);
|
|
236
256
|
return localJwks;
|
|
237
257
|
}
|
|
238
258
|
|
|
@@ -254,16 +274,16 @@ export function generateCode(length = 32): string {
|
|
|
254
274
|
* Generate a cryptographically strong Client Secret (hex string)
|
|
255
275
|
*/
|
|
256
276
|
export function generateClientSecret(length = 64): string {
|
|
257
|
-
const array = new Uint8Array(length);
|
|
277
|
+
const array = new Uint8Array(Math.ceil(length / 2));
|
|
258
278
|
crypto.getRandomValues(array);
|
|
259
|
-
return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
|
|
279
|
+
return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('').slice(0, length);
|
|
260
280
|
}
|
|
261
281
|
|
|
262
282
|
/**
|
|
263
283
|
* Get Issuer URL helper
|
|
264
284
|
*/
|
|
265
285
|
export function getIssuerUrl(config: OAuthConfig): string {
|
|
266
|
-
const issuerBaseUrl = config.convexSiteUrl ?? config.siteUrl;
|
|
286
|
+
const issuerBaseUrl = (config.convexSiteUrl ?? config.siteUrl).replace(/\/+$/, "");
|
|
267
287
|
const prefix = normalizePrefix(config.prefix);
|
|
268
288
|
return issuerBaseUrl + prefix;
|
|
269
289
|
}
|