@atproto/jwk-jose 0.1.11 → 0.2.0-next.0
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/CHANGELOG.md +19 -0
- package/LICENSE.txt +1 -1
- package/dist/index.js +1 -17
- package/dist/index.js.map +1 -1
- package/dist/jose-key.js +32 -36
- package/dist/jose-key.js.map +1 -1
- package/dist/util.js +1 -4
- package/dist/util.js.map +1 -1
- package/package.json +7 -6
- package/src/util.ts +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atproto/jwk-jose
|
|
2
2
|
|
|
3
|
+
## 0.2.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Drop support for Node.js 18 and 20. Node.js 22 is now the minimum supported version. Docker images now use Node.js 24.
|
|
8
|
+
|
|
9
|
+
- [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Convert to pure ESM. All packages now ship `"type": "module"` with ES module output and Node16 module resolution.
|
|
10
|
+
|
|
11
|
+
Node.js 22's `require()` compatibility layer can still load these packages in CommonJS code.
|
|
12
|
+
|
|
13
|
+
- [#4930](https://github.com/bluesky-social/atproto/pull/4930) [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9) Thanks [@devinivy](https://github.com/devinivy)! - Build with TypeScript 6.0. Emitted `.d.ts` files now use TypeScript 6's stricter `Uint8Array<ArrayBuffer>` typing in places where Web/Node APIs require buffer-backed (not shared-memory) byte arrays. Consumers compiling against these types on older TypeScript should see no runtime impact, but may need to widen or cast in spots that previously relied on `Uint8Array` defaulting to `<ArrayBufferLike>`.
|
|
14
|
+
|
|
15
|
+
Internal: tsconfig `moduleResolution: "node"` is silenced via `ignoreDeprecations: "6.0"` for now; the proper migration to `node16`/`bundler` resolution is deferred.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [[`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b), [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028), [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9)]:
|
|
20
|
+
- @atproto/jwk@0.7.0-next.0
|
|
21
|
+
|
|
3
22
|
## 0.1.11
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/LICENSE.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Dual MIT/Apache-2.0 License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2022-
|
|
3
|
+
Copyright (c) 2022-2026 Bluesky Social PBC, and Contributors
|
|
4
4
|
|
|
5
5
|
Except as otherwise noted in individual files, this software is licensed under the MIT license (<http://opensource.org/licenses/MIT>), or the Apache License, Version 2.0 (<http://www.apache.org/licenses/LICENSE-2.0>).
|
|
6
6
|
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./jose-key.js"), exports);
|
|
1
|
+
export * from './jose-key.js';
|
|
18
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA","sourcesContent":["export * from './jose-key.js'\n"]}
|
package/dist/jose-key.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const util_js_1 = require("./util.js");
|
|
7
|
-
const { JOSEError } = jose_1.errors;
|
|
8
|
-
class JoseKey extends jwk_1.Key {
|
|
1
|
+
import { SignJWT, errors, exportJWK, generateKeyPair, importJWK, importPKCS8, jwtVerify, } from 'jose';
|
|
2
|
+
import { JwkError, JwtCreateError, JwtVerifyError, Key, isPrivateJwk, jwkSchema, jwtHeaderSchema, jwtPayloadSchema, } from '@atproto/jwk';
|
|
3
|
+
import { either } from './util.js';
|
|
4
|
+
const { JOSEError } = errors;
|
|
5
|
+
export class JoseKey extends Key {
|
|
9
6
|
/**
|
|
10
7
|
* Some runtimes (e.g. Bun) require an `alg` second argument to be set when
|
|
11
8
|
* invoking `importJWK`. In order to be compatible with these runtimes, we
|
|
@@ -14,27 +11,27 @@ class JoseKey extends jwk_1.Key {
|
|
|
14
11
|
*/
|
|
15
12
|
async getKeyObj(alg) {
|
|
16
13
|
if (!this.algorithms.includes(alg)) {
|
|
17
|
-
throw new
|
|
14
|
+
throw new JwkError(`Key cannot be used with algorithm "${alg}"`);
|
|
18
15
|
}
|
|
19
16
|
try {
|
|
20
|
-
return await
|
|
17
|
+
return await importJWK(this.jwk, alg);
|
|
21
18
|
}
|
|
22
19
|
catch (cause) {
|
|
23
|
-
throw new
|
|
20
|
+
throw new JwkError('Failed to import JWK', undefined, { cause });
|
|
24
21
|
}
|
|
25
22
|
}
|
|
26
23
|
async createJwt(header, payload) {
|
|
27
24
|
try {
|
|
28
25
|
const { kid } = header;
|
|
29
26
|
if (kid && kid !== this.kid) {
|
|
30
|
-
throw new
|
|
27
|
+
throw new JwtCreateError(`Invalid "kid" (${kid}) used to sign with key "${this.kid}"`);
|
|
31
28
|
}
|
|
32
29
|
const { alg } = header;
|
|
33
30
|
if (!alg) {
|
|
34
|
-
throw new
|
|
31
|
+
throw new JwtCreateError('Missing "alg" in JWT header');
|
|
35
32
|
}
|
|
36
33
|
const keyObj = await this.getKeyObj(alg);
|
|
37
|
-
const jwtBuilder = new
|
|
34
|
+
const jwtBuilder = new SignJWT(payload).setProtectedHeader({
|
|
38
35
|
...header,
|
|
39
36
|
alg,
|
|
40
37
|
kid: this.kid,
|
|
@@ -44,30 +41,30 @@ class JoseKey extends jwk_1.Key {
|
|
|
44
41
|
}
|
|
45
42
|
catch (cause) {
|
|
46
43
|
if (cause instanceof JOSEError) {
|
|
47
|
-
throw new
|
|
44
|
+
throw new JwtCreateError(cause.message, cause.code, { cause });
|
|
48
45
|
}
|
|
49
46
|
else {
|
|
50
|
-
throw
|
|
47
|
+
throw JwtCreateError.from(cause);
|
|
51
48
|
}
|
|
52
49
|
}
|
|
53
50
|
}
|
|
54
51
|
async verifyJwt(token, options) {
|
|
55
52
|
try {
|
|
56
|
-
const result = await
|
|
53
|
+
const result = await jwtVerify(token, async ({ alg }) => this.getKeyObj(alg), { ...options, algorithms: this.algorithms });
|
|
57
54
|
// @NOTE if all tokens are signed exclusively through createJwt(), then
|
|
58
55
|
// there should be no need to parse the payload and headers here. But
|
|
59
56
|
// since the JWT could have been signed with the same key from somewhere
|
|
60
57
|
// else, let's parse it to ensure the integrity (and type safety) of the
|
|
61
58
|
// data.
|
|
62
|
-
const headerParsed =
|
|
59
|
+
const headerParsed = jwtHeaderSchema.safeParse(result.protectedHeader);
|
|
63
60
|
if (!headerParsed.success) {
|
|
64
|
-
throw new
|
|
61
|
+
throw new JwtVerifyError('Invalid JWT header', undefined, {
|
|
65
62
|
cause: headerParsed.error,
|
|
66
63
|
});
|
|
67
64
|
}
|
|
68
|
-
const payloadParsed =
|
|
65
|
+
const payloadParsed = jwtPayloadSchema.safeParse(result.payload);
|
|
69
66
|
if (!payloadParsed.success) {
|
|
70
|
-
throw new
|
|
67
|
+
throw new JwtVerifyError('Invalid JWT payload', undefined, {
|
|
71
68
|
cause: payloadParsed.error,
|
|
72
69
|
});
|
|
73
70
|
}
|
|
@@ -79,27 +76,27 @@ class JoseKey extends jwk_1.Key {
|
|
|
79
76
|
}
|
|
80
77
|
catch (cause) {
|
|
81
78
|
if (cause instanceof JOSEError) {
|
|
82
|
-
throw new
|
|
79
|
+
throw new JwtVerifyError(cause.message, cause.code, { cause });
|
|
83
80
|
}
|
|
84
81
|
else {
|
|
85
|
-
throw
|
|
82
|
+
throw JwtVerifyError.from(cause);
|
|
86
83
|
}
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
86
|
static async generateKeyPair(allowedAlgos = ['ES256'], options) {
|
|
90
87
|
if (!allowedAlgos.length) {
|
|
91
|
-
throw new
|
|
88
|
+
throw new JwkError('No algorithms provided for key generation');
|
|
92
89
|
}
|
|
93
90
|
const errors = [];
|
|
94
91
|
for (const alg of allowedAlgos) {
|
|
95
92
|
try {
|
|
96
|
-
return await
|
|
93
|
+
return await generateKeyPair(alg, options);
|
|
97
94
|
}
|
|
98
95
|
catch (err) {
|
|
99
96
|
errors.push(err);
|
|
100
97
|
}
|
|
101
98
|
}
|
|
102
|
-
throw new
|
|
99
|
+
throw new JwkError('Failed to generate key pair', undefined, {
|
|
103
100
|
cause: new AggregateError(errors, 'None of the algorithms worked'),
|
|
104
101
|
});
|
|
105
102
|
}
|
|
@@ -121,7 +118,7 @@ class JoseKey extends jwk_1.Key {
|
|
|
121
118
|
if (input.startsWith('{')) {
|
|
122
119
|
return this.fromJWK(input, kid);
|
|
123
120
|
}
|
|
124
|
-
throw new
|
|
121
|
+
throw new JwkError('Invalid input');
|
|
125
122
|
}
|
|
126
123
|
if (typeof input === 'object') {
|
|
127
124
|
// Jwk
|
|
@@ -131,18 +128,18 @@ class JoseKey extends jwk_1.Key {
|
|
|
131
128
|
// KeyLike
|
|
132
129
|
return this.fromKeyLike(input, kid);
|
|
133
130
|
}
|
|
134
|
-
throw new
|
|
131
|
+
throw new JwkError('Invalid input');
|
|
135
132
|
}
|
|
136
133
|
/**
|
|
137
134
|
* @see {@link exportJWK}
|
|
138
135
|
*/
|
|
139
136
|
static async fromKeyLike(keyLike, kid, alg) {
|
|
140
|
-
const jwk = await
|
|
137
|
+
const jwk = await exportJWK(keyLike);
|
|
141
138
|
if (alg) {
|
|
142
139
|
if (!jwk.alg)
|
|
143
140
|
jwk.alg = alg;
|
|
144
141
|
else if (jwk.alg !== alg)
|
|
145
|
-
throw new
|
|
142
|
+
throw new JwkError('Invalid "alg" in JWK');
|
|
146
143
|
}
|
|
147
144
|
return this.fromJWK(jwk, kid);
|
|
148
145
|
}
|
|
@@ -150,22 +147,21 @@ class JoseKey extends jwk_1.Key {
|
|
|
150
147
|
* @see {@link importPKCS8}
|
|
151
148
|
*/
|
|
152
149
|
static async fromPKCS8(pem, alg, kid) {
|
|
153
|
-
const keyLike = await
|
|
150
|
+
const keyLike = await importPKCS8(pem, alg, { extractable: true });
|
|
154
151
|
return this.fromKeyLike(keyLike, kid);
|
|
155
152
|
}
|
|
156
153
|
static async fromJWK(input, inputKid) {
|
|
157
154
|
const jwk = typeof input === 'string' ? JSON.parse(input) : input;
|
|
158
155
|
if (!jwk || typeof jwk !== 'object')
|
|
159
|
-
throw new
|
|
160
|
-
const kid =
|
|
156
|
+
throw new JwkError('Invalid JWK');
|
|
157
|
+
const kid = either(jwk.kid, inputKid);
|
|
161
158
|
// Backwards compatibility with old behavior
|
|
162
|
-
if (jwk.use != null &&
|
|
159
|
+
if (jwk.use != null && isPrivateJwk(jwk)) {
|
|
163
160
|
console.warn('Deprecation warning: Private JWK with a "use" property will be rejected in the future. Please remove replace "use" with (valid) "key_ops".');
|
|
164
161
|
jwk.key_ops ??= jwk.use === 'sig' ? ['sign'] : ['encrypt'];
|
|
165
162
|
delete jwk.use;
|
|
166
163
|
}
|
|
167
|
-
return new JoseKey(
|
|
164
|
+
return new JoseKey(jwkSchema.parse({ ...jwk, kid }));
|
|
168
165
|
}
|
|
169
166
|
}
|
|
170
|
-
exports.JoseKey = JoseKey;
|
|
171
167
|
//# sourceMappingURL=jose-key.js.map
|
package/dist/jose-key.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jose-key.js","sourceRoot":"","sources":["../src/jose-key.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type GenerateKeyPairOptions,\n type GenerateKeyPairResult,\n type JWK,\n type JWTVerifyOptions,\n type KeyLike,\n SignJWT,\n errors,\n exportJWK,\n generateKeyPair,\n importJWK,\n importPKCS8,\n jwtVerify,\n} from 'jose'\nimport {\n Jwk,\n JwkError,\n JwtCreateError,\n JwtHeader,\n JwtPayload,\n JwtVerifyError,\n Key,\n SignedJwt,\n VerifyOptions,\n VerifyResult,\n isPrivateJwk,\n jwkSchema,\n jwtHeaderSchema,\n jwtPayloadSchema,\n} from '@atproto/jwk'\nimport { RequiredKey, either } from './util.js'\n\nconst { JOSEError } = errors\n\nexport {\n type GenerateKeyPairOptions,\n type GenerateKeyPairResult,\n type Jwk,\n type JwtHeader,\n type JwtPayload,\n type KeyLike,\n type SignedJwt,\n type VerifyOptions,\n}\n\nexport class JoseKey<J extends Jwk = Jwk> extends Key<J> {\n /**\n * Some runtimes (e.g. Bun) require an `alg` second argument to be set when\n * invoking `importJWK`. In order to be compatible with these runtimes, we\n * provide the following method to ensure the `alg` is always set. We also\n * take the opportunity to ensure that the `alg` is compatible with this key.\n */\n protected async getKeyObj(alg: string) {\n if (!this.algorithms.includes(alg)) {\n throw new JwkError(`Key cannot be used with algorithm \"${alg}\"`)\n }\n try {\n return await importJWK(this.jwk as JWK, alg)\n } catch (cause) {\n throw new JwkError('Failed to import JWK', undefined, { cause })\n }\n }\n\n async createJwt(header: JwtHeader, payload: JwtPayload): Promise<SignedJwt> {\n try {\n const { kid } = header\n if (kid && kid !== this.kid) {\n throw new JwtCreateError(\n `Invalid \"kid\" (${kid}) used to sign with key \"${this.kid}\"`,\n )\n }\n\n const { alg } = header\n if (!alg) {\n throw new JwtCreateError('Missing \"alg\" in JWT header')\n }\n\n const keyObj = await this.getKeyObj(alg)\n const jwtBuilder = new SignJWT(payload).setProtectedHeader({\n ...header,\n alg,\n kid: this.kid,\n })\n\n const signedJwt = await jwtBuilder.sign(keyObj)\n\n return signedJwt as SignedJwt\n } catch (cause) {\n if (cause instanceof JOSEError) {\n throw new JwtCreateError(cause.message, cause.code, { cause })\n } else {\n throw JwtCreateError.from(cause)\n }\n }\n }\n\n async verifyJwt<C extends string = never>(\n token: SignedJwt,\n options?: VerifyOptions<C>,\n ): Promise<VerifyResult<C>> {\n try {\n const result = await jwtVerify(\n token,\n async ({ alg }) => this.getKeyObj(alg),\n { ...options, algorithms: this.algorithms } as JWTVerifyOptions,\n )\n\n // @NOTE if all tokens are signed exclusively through createJwt(), then\n // there should be no need to parse the payload and headers here. But\n // since the JWT could have been signed with the same key from somewhere\n // else, let's parse it to ensure the integrity (and type safety) of the\n // data.\n const headerParsed = jwtHeaderSchema.safeParse(result.protectedHeader)\n if (!headerParsed.success) {\n throw new JwtVerifyError('Invalid JWT header', undefined, {\n cause: headerParsed.error,\n })\n }\n\n const payloadParsed = jwtPayloadSchema.safeParse(result.payload)\n if (!payloadParsed.success) {\n throw new JwtVerifyError('Invalid JWT payload', undefined, {\n cause: payloadParsed.error,\n })\n }\n\n return {\n protectedHeader: headerParsed.data,\n // \"requiredClaims\" enforced by jwtVerify()\n payload: payloadParsed.data as RequiredKey<JwtPayload, C>,\n }\n } catch (cause) {\n if (cause instanceof JOSEError) {\n throw new JwtVerifyError(cause.message, cause.code, { cause })\n } else {\n throw JwtVerifyError.from(cause)\n }\n }\n }\n\n static async generateKeyPair(\n allowedAlgos: readonly string[] = ['ES256'],\n options?: GenerateKeyPairOptions,\n ) {\n if (!allowedAlgos.length) {\n throw new JwkError('No algorithms provided for key generation')\n }\n\n const errors: unknown[] = []\n for (const alg of allowedAlgos) {\n try {\n return await generateKeyPair(alg, options)\n } catch (err) {\n errors.push(err)\n }\n }\n\n throw new JwkError('Failed to generate key pair', undefined, {\n cause: new AggregateError(errors, 'None of the algorithms worked'),\n })\n }\n\n static async generate(\n allowedAlgos: string[] = ['ES256'],\n kid?: string,\n options?: Omit<GenerateKeyPairOptions, 'extractable'>,\n ): Promise<JoseKey> {\n const kp = await this.generateKeyPair(allowedAlgos, {\n ...options,\n extractable: true,\n })\n return this.fromKeyLike(kp.privateKey, kid)\n }\n\n static async fromImportable(\n input: string | KeyLike | Jwk,\n kid?: string,\n ): Promise<JoseKey> {\n if (typeof input === 'string') {\n // PKCS8\n if (input.startsWith('-----')) {\n // The \"alg\" is only needed in WebCrypto (NodeJS will be fine)\n return this.fromPKCS8(input, '', kid)\n }\n\n // Jwk (string)\n if (input.startsWith('{')) {\n return this.fromJWK(input, kid)\n }\n\n throw new JwkError('Invalid input')\n }\n\n if (typeof input === 'object') {\n // Jwk\n if ('kty' in input || 'alg' in input) {\n return this.fromJWK(input, kid)\n }\n\n // KeyLike\n return this.fromKeyLike(input, kid)\n }\n\n throw new JwkError('Invalid input')\n }\n\n /**\n * @see {@link exportJWK}\n */\n static async fromKeyLike(\n keyLike: KeyLike | Uint8Array,\n kid?: string,\n alg?: string,\n ): Promise<JoseKey> {\n const jwk = await exportJWK(keyLike)\n if (alg) {\n if (!jwk.alg) jwk.alg = alg\n else if (jwk.alg !== alg) throw new JwkError('Invalid \"alg\" in JWK')\n }\n return this.fromJWK(jwk, kid)\n }\n\n /**\n * @see {@link importPKCS8}\n */\n static async fromPKCS8(\n pem: string,\n alg: string,\n kid?: string,\n ): Promise<JoseKey> {\n const keyLike = await importPKCS8(pem, alg, { extractable: true })\n return this.fromKeyLike(keyLike, kid)\n }\n\n static async fromJWK(\n input: string | Record<string, unknown>,\n inputKid?: string,\n ): Promise<JoseKey> {\n const jwk = typeof input === 'string' ? JSON.parse(input) : input\n if (!jwk || typeof jwk !== 'object') throw new JwkError('Invalid JWK')\n\n const kid = either(jwk.kid, inputKid)\n\n // Backwards compatibility with old behavior\n if (jwk.use != null && isPrivateJwk(jwk)) {\n console.warn(\n 'Deprecation warning: Private JWK with a \"use\" property will be rejected in the future. Please remove replace \"use\" with (valid) \"key_ops\".',\n )\n jwk.key_ops ??= jwk.use === 'sig' ? ['sign'] : ['encrypt']\n delete jwk.use\n }\n\n return new JoseKey<Jwk>(jwkSchema.parse({ ...jwk, kid }))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"jose-key.js","sourceRoot":"","sources":["../src/jose-key.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type GenerateKeyPairOptions,\n type GenerateKeyPairResult,\n type JWK,\n type JWTVerifyOptions,\n type KeyLike,\n SignJWT,\n errors,\n exportJWK,\n generateKeyPair,\n importJWK,\n importPKCS8,\n jwtVerify,\n} from 'jose'\nimport {\n Jwk,\n JwkError,\n JwtCreateError,\n JwtHeader,\n JwtPayload,\n JwtVerifyError,\n Key,\n SignedJwt,\n VerifyOptions,\n VerifyResult,\n isPrivateJwk,\n jwkSchema,\n jwtHeaderSchema,\n jwtPayloadSchema,\n} from '@atproto/jwk'\nimport { RequiredKey, either } from './util.js'\n\nconst { JOSEError } = errors\n\nexport {\n type GenerateKeyPairOptions,\n type GenerateKeyPairResult,\n type Jwk,\n type JwtHeader,\n type JwtPayload,\n type KeyLike,\n type SignedJwt,\n type VerifyOptions,\n}\n\nexport class JoseKey<J extends Jwk = Jwk> extends Key<J> {\n /**\n * Some runtimes (e.g. Bun) require an `alg` second argument to be set when\n * invoking `importJWK`. In order to be compatible with these runtimes, we\n * provide the following method to ensure the `alg` is always set. We also\n * take the opportunity to ensure that the `alg` is compatible with this key.\n */\n protected async getKeyObj(alg: string) {\n if (!this.algorithms.includes(alg)) {\n throw new JwkError(`Key cannot be used with algorithm \"${alg}\"`)\n }\n try {\n return await importJWK(this.jwk as JWK, alg)\n } catch (cause) {\n throw new JwkError('Failed to import JWK', undefined, { cause })\n }\n }\n\n async createJwt(header: JwtHeader, payload: JwtPayload): Promise<SignedJwt> {\n try {\n const { kid } = header\n if (kid && kid !== this.kid) {\n throw new JwtCreateError(\n `Invalid \"kid\" (${kid}) used to sign with key \"${this.kid}\"`,\n )\n }\n\n const { alg } = header\n if (!alg) {\n throw new JwtCreateError('Missing \"alg\" in JWT header')\n }\n\n const keyObj = await this.getKeyObj(alg)\n const jwtBuilder = new SignJWT(payload).setProtectedHeader({\n ...header,\n alg,\n kid: this.kid,\n })\n\n const signedJwt = await jwtBuilder.sign(keyObj)\n\n return signedJwt as SignedJwt\n } catch (cause) {\n if (cause instanceof JOSEError) {\n throw new JwtCreateError(cause.message, cause.code, { cause })\n } else {\n throw JwtCreateError.from(cause)\n }\n }\n }\n\n async verifyJwt<C extends string = never>(\n token: SignedJwt,\n options?: VerifyOptions<C>,\n ): Promise<VerifyResult<C>> {\n try {\n const result = await jwtVerify(\n token,\n async ({ alg }) => this.getKeyObj(alg),\n { ...options, algorithms: this.algorithms } as JWTVerifyOptions,\n )\n\n // @NOTE if all tokens are signed exclusively through createJwt(), then\n // there should be no need to parse the payload and headers here. But\n // since the JWT could have been signed with the same key from somewhere\n // else, let's parse it to ensure the integrity (and type safety) of the\n // data.\n const headerParsed = jwtHeaderSchema.safeParse(result.protectedHeader)\n if (!headerParsed.success) {\n throw new JwtVerifyError('Invalid JWT header', undefined, {\n cause: headerParsed.error,\n })\n }\n\n const payloadParsed = jwtPayloadSchema.safeParse(result.payload)\n if (!payloadParsed.success) {\n throw new JwtVerifyError('Invalid JWT payload', undefined, {\n cause: payloadParsed.error,\n })\n }\n\n return {\n protectedHeader: headerParsed.data,\n // \"requiredClaims\" enforced by jwtVerify()\n payload: payloadParsed.data as RequiredKey<JwtPayload, C>,\n }\n } catch (cause) {\n if (cause instanceof JOSEError) {\n throw new JwtVerifyError(cause.message, cause.code, { cause })\n } else {\n throw JwtVerifyError.from(cause)\n }\n }\n }\n\n static async generateKeyPair(\n allowedAlgos: readonly string[] = ['ES256'],\n options?: GenerateKeyPairOptions,\n ) {\n if (!allowedAlgos.length) {\n throw new JwkError('No algorithms provided for key generation')\n }\n\n const errors: unknown[] = []\n for (const alg of allowedAlgos) {\n try {\n return await generateKeyPair(alg, options)\n } catch (err) {\n errors.push(err)\n }\n }\n\n throw new JwkError('Failed to generate key pair', undefined, {\n cause: new AggregateError(errors, 'None of the algorithms worked'),\n })\n }\n\n static async generate(\n allowedAlgos: string[] = ['ES256'],\n kid?: string,\n options?: Omit<GenerateKeyPairOptions, 'extractable'>,\n ): Promise<JoseKey> {\n const kp = await this.generateKeyPair(allowedAlgos, {\n ...options,\n extractable: true,\n })\n return this.fromKeyLike(kp.privateKey, kid)\n }\n\n static async fromImportable(\n input: string | KeyLike | Jwk,\n kid?: string,\n ): Promise<JoseKey> {\n if (typeof input === 'string') {\n // PKCS8\n if (input.startsWith('-----')) {\n // The \"alg\" is only needed in WebCrypto (NodeJS will be fine)\n return this.fromPKCS8(input, '', kid)\n }\n\n // Jwk (string)\n if (input.startsWith('{')) {\n return this.fromJWK(input, kid)\n }\n\n throw new JwkError('Invalid input')\n }\n\n if (typeof input === 'object') {\n // Jwk\n if ('kty' in input || 'alg' in input) {\n return this.fromJWK(input, kid)\n }\n\n // KeyLike\n return this.fromKeyLike(input, kid)\n }\n\n throw new JwkError('Invalid input')\n }\n\n /**\n * @see {@link exportJWK}\n */\n static async fromKeyLike(\n keyLike: KeyLike | Uint8Array,\n kid?: string,\n alg?: string,\n ): Promise<JoseKey> {\n const jwk = await exportJWK(keyLike)\n if (alg) {\n if (!jwk.alg) jwk.alg = alg\n else if (jwk.alg !== alg) throw new JwkError('Invalid \"alg\" in JWK')\n }\n return this.fromJWK(jwk, kid)\n }\n\n /**\n * @see {@link importPKCS8}\n */\n static async fromPKCS8(\n pem: string,\n alg: string,\n kid?: string,\n ): Promise<JoseKey> {\n const keyLike = await importPKCS8(pem, alg, { extractable: true })\n return this.fromKeyLike(keyLike, kid)\n }\n\n static async fromJWK(\n input: string | Record<string, unknown>,\n inputKid?: string,\n ): Promise<JoseKey> {\n const jwk = typeof input === 'string' ? JSON.parse(input) : input\n if (!jwk || typeof jwk !== 'object') throw new JwkError('Invalid JWK')\n\n const kid = either(jwk.kid, inputKid)\n\n // Backwards compatibility with old behavior\n if (jwk.use != null && isPrivateJwk(jwk)) {\n console.warn(\n 'Deprecation warning: Private JWK with a \"use\" property will be rejected in the future. Please remove replace \"use\" with (valid) \"key_ops\".',\n )\n jwk.key_ops ??= jwk.use === 'sig' ? ['sign'] : ['encrypt']\n delete jwk.use\n }\n\n return new JoseKey<Jwk>(jwkSchema.parse({ ...jwk, kid }))\n }\n}\n"]}
|
package/dist/util.js
CHANGED
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,MAAM,CACpB,CAAK,EACL,CAAK;IAEL,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,SAAS,CAAC,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACpD,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,IAAI,SAAS,CAAA;AAC5B,CAAC","sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Simplify<T> = { [K in keyof T]: T[K] } & {}\n\nexport type RequiredKey<T, K extends keyof T = never> = Simplify<\n T & {\n [L in K]-?: unknown extends T[L]\n ? NonNullable<unknown> | null\n : Exclude<T[L], undefined>\n }\n>\n\nexport function either<T extends string | number | boolean>(\n a?: T,\n b?: T,\n): T | undefined {\n if (a != null && b != null && a !== b) {\n throw new TypeError(`Expected \"${b}\", got \"${a}\"`)\n }\n return a ?? b ?? undefined\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/jwk-jose",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-next.0",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": ">=22"
|
|
6
|
+
},
|
|
4
7
|
"license": "MIT",
|
|
5
8
|
"description": "`jose` based implementation of @atproto/jwk Key's",
|
|
6
9
|
"keywords": [
|
|
@@ -14,9 +17,7 @@
|
|
|
14
17
|
"url": "https://github.com/bluesky-social/atproto",
|
|
15
18
|
"directory": "packages/oauth/jwk-jose"
|
|
16
19
|
},
|
|
17
|
-
"type": "
|
|
18
|
-
"main": "dist/index.js",
|
|
19
|
-
"types": "dist/index.d.ts",
|
|
20
|
+
"type": "module",
|
|
20
21
|
"exports": {
|
|
21
22
|
".": {
|
|
22
23
|
"types": "./dist/index.d.ts",
|
|
@@ -25,10 +26,10 @@
|
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
27
28
|
"jose": "^5.2.0",
|
|
28
|
-
"@atproto/jwk": "0.
|
|
29
|
+
"@atproto/jwk": "^0.7.0-next.0"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
|
-
"typescript": "^
|
|
32
|
+
"typescript": "^6.0.3"
|
|
32
33
|
},
|
|
33
34
|
"scripts": {
|
|
34
35
|
"build": "tsc --build tsconfig.build.json"
|
package/src/util.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/jose-key.ts","./src/util.ts"],"version":"
|
|
1
|
+
{"root":["./src/index.ts","./src/jose-key.ts","./src/util.ts"],"version":"6.0.3"}
|