@atproto/jwk 0.6.0 → 0.7.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 +12 -0
- package/LICENSE.txt +1 -1
- package/dist/alg.js +8 -11
- package/dist/alg.js.map +1 -1
- package/dist/errors.js +15 -36
- package/dist/errors.js.map +1 -1
- package/dist/index.js +10 -28
- package/dist/index.js.map +1 -1
- package/dist/jwk.js +77 -89
- package/dist/jwk.js.map +1 -1
- package/dist/jwks.js +8 -11
- package/dist/jwks.js.map +1 -1
- package/dist/jwt-decode.js +8 -11
- package/dist/jwt-decode.js.map +1 -1
- package/dist/jwt-verify.js +1 -2
- package/dist/jwt.js +97 -102
- package/dist/jwt.js.map +1 -1
- package/dist/key.js +142 -152
- package/dist/key.js.map +1 -1
- package/dist/keyset.js +153 -169
- package/dist/keyset.js.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +19 -28
- package/dist/util.js.map +1 -1
- package/package.json +7 -6
- package/src/jwk.ts +1 -1
- package/src/util.ts +2 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/dist/key.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
3
2
|
var useValue = arguments.length > 2;
|
|
4
3
|
for (var i = 0; i < initializers.length; i++) {
|
|
@@ -33,176 +32,167 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
33
32
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
34
33
|
done = true;
|
|
35
34
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const jwk_js_1 = require("./jwk.js");
|
|
40
|
-
const util_js_1 = require("./util.js");
|
|
35
|
+
import { jwkAlgorithms } from './alg.js';
|
|
36
|
+
import { PUBLIC_KEY_USAGE, hasSharedSecretJwk, isEncKeyUsage, isPrivateJwk, isPublicKeyUsage, isSigKeyUsage, jwkPubSchema, jwkSchema, } from './jwk.js';
|
|
37
|
+
import { cachedGetter } from './util.js';
|
|
41
38
|
let Key = (() => {
|
|
42
|
-
var _a;
|
|
43
39
|
let _instanceExtraInitializers = [];
|
|
44
40
|
let _get_isPrivate_decorators;
|
|
45
41
|
let _get_isSymetric_decorators;
|
|
46
42
|
let _get_publicJwk_decorators;
|
|
47
43
|
let _get_bareJwk_decorators;
|
|
48
44
|
let _get_algorithms_decorators;
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
get
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
get
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
45
|
+
return class Key {
|
|
46
|
+
static {
|
|
47
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
48
|
+
_get_isPrivate_decorators = [cachedGetter];
|
|
49
|
+
_get_isSymetric_decorators = [cachedGetter];
|
|
50
|
+
_get_publicJwk_decorators = [cachedGetter];
|
|
51
|
+
_get_bareJwk_decorators = [cachedGetter];
|
|
52
|
+
_get_algorithms_decorators = [cachedGetter];
|
|
53
|
+
__esDecorate(this, null, _get_isPrivate_decorators, { kind: "getter", name: "isPrivate", static: false, private: false, access: { has: obj => "isPrivate" in obj, get: obj => obj.isPrivate }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
54
|
+
__esDecorate(this, null, _get_isSymetric_decorators, { kind: "getter", name: "isSymetric", static: false, private: false, access: { has: obj => "isSymetric" in obj, get: obj => obj.isSymetric }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
55
|
+
__esDecorate(this, null, _get_publicJwk_decorators, { kind: "getter", name: "publicJwk", static: false, private: false, access: { has: obj => "publicJwk" in obj, get: obj => obj.publicJwk }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
56
|
+
__esDecorate(this, null, _get_bareJwk_decorators, { kind: "getter", name: "bareJwk", static: false, private: false, access: { has: obj => "bareJwk" in obj, get: obj => obj.bareJwk }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
57
|
+
__esDecorate(this, null, _get_algorithms_decorators, { kind: "getter", name: "algorithms", static: false, private: false, access: { has: obj => "algorithms" in obj, get: obj => obj.algorithms }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
58
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
59
|
+
}
|
|
60
|
+
constructor(jwk) {
|
|
61
|
+
this.jwk = (__runInitializers(this, _instanceExtraInitializers), jwk);
|
|
62
|
+
}
|
|
63
|
+
get isPrivate() {
|
|
64
|
+
return isPrivateJwk(this.jwk);
|
|
65
|
+
}
|
|
66
|
+
get isSymetric() {
|
|
67
|
+
return hasSharedSecretJwk(this.jwk);
|
|
68
|
+
}
|
|
69
|
+
get privateJwk() {
|
|
70
|
+
if (!this.isPrivate)
|
|
71
|
+
return undefined;
|
|
72
|
+
return this.jwk;
|
|
73
|
+
}
|
|
74
|
+
get publicJwk() {
|
|
75
|
+
if (this.isSymetric)
|
|
76
|
+
return undefined;
|
|
77
|
+
if (!this.isPrivate)
|
|
67
78
|
return this.jwk;
|
|
79
|
+
const validated = jwkPubSchema.safeParse({
|
|
80
|
+
...this.jwk,
|
|
81
|
+
d: undefined,
|
|
82
|
+
k: undefined,
|
|
83
|
+
use: undefined,
|
|
84
|
+
key_ops: buildPublicKeyOps(this.keyOps) ?? PUBLIC_KEY_USAGE,
|
|
85
|
+
});
|
|
86
|
+
// One reason why the parsing might fail is if key_ops is empty. This check
|
|
87
|
+
// also allows to future proof the code (e.g if another type of private key
|
|
88
|
+
// is added that uses a different property than "d" or "k" to store its
|
|
89
|
+
// private value).
|
|
90
|
+
if (!validated.success)
|
|
91
|
+
return undefined;
|
|
92
|
+
return Object.freeze(validated.data);
|
|
93
|
+
}
|
|
94
|
+
get bareJwk() {
|
|
95
|
+
if (this.isSymetric)
|
|
96
|
+
return undefined;
|
|
97
|
+
const { kty, crv, e, n, x, y } = this.jwk;
|
|
98
|
+
return Object.freeze(jwkSchema.parse({ crv, e, kty, n, x, y }));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* @note Only defined on public keys
|
|
102
|
+
*/
|
|
103
|
+
get use() {
|
|
104
|
+
return this.jwk.use;
|
|
105
|
+
}
|
|
106
|
+
get keyOps() {
|
|
107
|
+
return this.jwk.key_ops;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The (forced) algorithm to use. If not provided, the key will be usable with
|
|
111
|
+
* any of the algorithms in {@link algorithms}.
|
|
112
|
+
*
|
|
113
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7518#section-3.1 | "alg" (Algorithm) Header Parameter Values for JWS}
|
|
114
|
+
*/
|
|
115
|
+
get alg() {
|
|
116
|
+
return this.jwk.alg;
|
|
117
|
+
}
|
|
118
|
+
get kid() {
|
|
119
|
+
return this.jwk.kid;
|
|
120
|
+
}
|
|
121
|
+
get crv() {
|
|
122
|
+
return this.jwk.crv;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* All the algorithms that this key can be used with. If `alg` is provided,
|
|
126
|
+
* this set will only contain that algorithm.
|
|
127
|
+
*/
|
|
128
|
+
get algorithms() {
|
|
129
|
+
return Object.freeze(Array.from(jwkAlgorithms(this.jwk)));
|
|
130
|
+
}
|
|
131
|
+
get isRevoked() {
|
|
132
|
+
return this.jwk.revoked != null;
|
|
133
|
+
}
|
|
134
|
+
isActive(options) {
|
|
135
|
+
if (!options?.allowRevoked && this.isRevoked)
|
|
136
|
+
return false;
|
|
137
|
+
const tolerance = options?.clockTolerance ?? 0;
|
|
138
|
+
if (tolerance !== Infinity) {
|
|
139
|
+
const now = options?.currentDate?.getTime() ?? Date.now();
|
|
140
|
+
const { exp, nbf } = this.jwk;
|
|
141
|
+
if (nbf != null && !(now >= nbf * 1e3 - tolerance))
|
|
142
|
+
return false;
|
|
143
|
+
if (exp != null && !(now < exp * 1e3 + tolerance))
|
|
144
|
+
return false;
|
|
68
145
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
use: undefined,
|
|
79
|
-
key_ops: buildPublicKeyOps(this.keyOps) ?? jwk_js_1.PUBLIC_KEY_USAGE,
|
|
80
|
-
});
|
|
81
|
-
// One reason why the parsing might fail is if key_ops is empty. This check
|
|
82
|
-
// also allows to future proof the code (e.g if another type of private key
|
|
83
|
-
// is added that uses a different property than "d" or "k" to store its
|
|
84
|
-
// private value).
|
|
85
|
-
if (!validated.success)
|
|
86
|
-
return undefined;
|
|
87
|
-
return Object.freeze(validated.data);
|
|
88
|
-
}
|
|
89
|
-
get bareJwk() {
|
|
90
|
-
if (this.isSymetric)
|
|
91
|
-
return undefined;
|
|
92
|
-
const { kty, crv, e, n, x, y } = this.jwk;
|
|
93
|
-
return Object.freeze(jwk_js_1.jwkSchema.parse({ crv, e, kty, n, x, y }));
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* @note Only defined on public keys
|
|
97
|
-
*/
|
|
98
|
-
get use() {
|
|
99
|
-
return this.jwk.use;
|
|
100
|
-
}
|
|
101
|
-
get keyOps() {
|
|
102
|
-
return this.jwk.key_ops;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* The (forced) algorithm to use. If not provided, the key will be usable with
|
|
106
|
-
* any of the algorithms in {@link algorithms}.
|
|
107
|
-
*
|
|
108
|
-
* @see {@link https://datatracker.ietf.org/doc/html/rfc7518#section-3.1 | "alg" (Algorithm) Header Parameter Values for JWS}
|
|
109
|
-
*/
|
|
110
|
-
get alg() {
|
|
111
|
-
return this.jwk.alg;
|
|
112
|
-
}
|
|
113
|
-
get kid() {
|
|
114
|
-
return this.jwk.kid;
|
|
115
|
-
}
|
|
116
|
-
get crv() {
|
|
117
|
-
return this.jwk.crv;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* All the algorithms that this key can be used with. If `alg` is provided,
|
|
121
|
-
* this set will only contain that algorithm.
|
|
122
|
-
*/
|
|
123
|
-
get algorithms() {
|
|
124
|
-
return Object.freeze(Array.from((0, alg_js_1.jwkAlgorithms)(this.jwk)));
|
|
125
|
-
}
|
|
126
|
-
get isRevoked() {
|
|
127
|
-
return this.jwk.revoked != null;
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
matches(opts) {
|
|
149
|
+
if (opts.kid != null) {
|
|
150
|
+
const matchesKid = Array.isArray(opts.kid)
|
|
151
|
+
? this.kid != null && opts.kid.includes(this.kid)
|
|
152
|
+
: this.kid === opts.kid;
|
|
153
|
+
if (!matchesKid)
|
|
154
|
+
return false;
|
|
128
155
|
}
|
|
129
|
-
|
|
130
|
-
|
|
156
|
+
if (opts.alg != null) {
|
|
157
|
+
const matchesAlg = Array.isArray(opts.alg)
|
|
158
|
+
? opts.alg.some((a) => this.algorithms.includes(a))
|
|
159
|
+
: this.algorithms.includes(opts.alg);
|
|
160
|
+
if (!matchesAlg)
|
|
131
161
|
return false;
|
|
132
|
-
const tolerance = options?.clockTolerance ?? 0;
|
|
133
|
-
if (tolerance !== Infinity) {
|
|
134
|
-
const now = options?.currentDate?.getTime() ?? Date.now();
|
|
135
|
-
const { exp, nbf } = this.jwk;
|
|
136
|
-
if (nbf != null && !(now >= nbf * 1e3 - tolerance))
|
|
137
|
-
return false;
|
|
138
|
-
if (exp != null && !(now < exp * 1e3 + tolerance))
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
return true;
|
|
142
162
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
(opts.usage === 'encrypt' && this.keyOps.includes('decrypt')) ||
|
|
165
|
-
(opts.usage === 'wrapKey' && this.keyOps.includes('unwrapKey'));
|
|
166
|
-
if (!matchesOps)
|
|
167
|
-
return false;
|
|
168
|
-
const matchesUse = this.use == null ||
|
|
169
|
-
(this.use === 'sig' && (0, jwk_js_1.isSigKeyUsage)(opts.usage)) ||
|
|
170
|
-
(this.use === 'enc' && (0, jwk_js_1.isEncKeyUsage)(opts.usage));
|
|
171
|
-
if (!matchesUse)
|
|
172
|
-
return false;
|
|
173
|
-
// @NOTE This is only relevant when "key_ops" and "use" are undefined.
|
|
174
|
-
// This line also ensures that when "opts.usage" is a private key usage
|
|
175
|
-
// (e.g. "sign"), the key is indeed a private key.
|
|
176
|
-
const matchesKeyType = this.isPrivate || (0, jwk_js_1.isPublicKeyUsage)(opts.usage);
|
|
177
|
-
if (!matchesKeyType)
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
return true;
|
|
163
|
+
if (opts.usage != null) {
|
|
164
|
+
const matchesOps = this.keyOps == null ||
|
|
165
|
+
this.keyOps.includes(opts.usage) ||
|
|
166
|
+
// @NOTE Because this.jwk represents the private key (typically used for
|
|
167
|
+
// private operations), the public counterpart operations are allowed.
|
|
168
|
+
(opts.usage === 'verify' && this.keyOps.includes('sign')) ||
|
|
169
|
+
(opts.usage === 'encrypt' && this.keyOps.includes('decrypt')) ||
|
|
170
|
+
(opts.usage === 'wrapKey' && this.keyOps.includes('unwrapKey'));
|
|
171
|
+
if (!matchesOps)
|
|
172
|
+
return false;
|
|
173
|
+
const matchesUse = this.use == null ||
|
|
174
|
+
(this.use === 'sig' && isSigKeyUsage(opts.usage)) ||
|
|
175
|
+
(this.use === 'enc' && isEncKeyUsage(opts.usage));
|
|
176
|
+
if (!matchesUse)
|
|
177
|
+
return false;
|
|
178
|
+
// @NOTE This is only relevant when "key_ops" and "use" are undefined.
|
|
179
|
+
// This line also ensures that when "opts.usage" is a private key usage
|
|
180
|
+
// (e.g. "sign"), the key is indeed a private key.
|
|
181
|
+
const matchesKeyType = this.isPrivate || isPublicKeyUsage(opts.usage);
|
|
182
|
+
if (!matchesKeyType)
|
|
183
|
+
return false;
|
|
181
184
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
_get_isPrivate_decorators = [util_js_1.cachedGetter];
|
|
186
|
-
_get_isSymetric_decorators = [util_js_1.cachedGetter];
|
|
187
|
-
_get_publicJwk_decorators = [util_js_1.cachedGetter];
|
|
188
|
-
_get_bareJwk_decorators = [util_js_1.cachedGetter];
|
|
189
|
-
_get_algorithms_decorators = [util_js_1.cachedGetter];
|
|
190
|
-
__esDecorate(_a, null, _get_isPrivate_decorators, { kind: "getter", name: "isPrivate", static: false, private: false, access: { has: obj => "isPrivate" in obj, get: obj => obj.isPrivate }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
191
|
-
__esDecorate(_a, null, _get_isSymetric_decorators, { kind: "getter", name: "isSymetric", static: false, private: false, access: { has: obj => "isSymetric" in obj, get: obj => obj.isSymetric }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
192
|
-
__esDecorate(_a, null, _get_publicJwk_decorators, { kind: "getter", name: "publicJwk", static: false, private: false, access: { has: obj => "publicJwk" in obj, get: obj => obj.publicJwk }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
193
|
-
__esDecorate(_a, null, _get_bareJwk_decorators, { kind: "getter", name: "bareJwk", static: false, private: false, access: { has: obj => "bareJwk" in obj, get: obj => obj.bareJwk }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
194
|
-
__esDecorate(_a, null, _get_algorithms_decorators, { kind: "getter", name: "algorithms", static: false, private: false, access: { has: obj => "algorithms" in obj, get: obj => obj.algorithms }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
195
|
-
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
196
|
-
})(),
|
|
197
|
-
_a;
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
198
188
|
})();
|
|
199
|
-
|
|
189
|
+
export { Key };
|
|
200
190
|
function buildPublicKeyOps(keyUsages) {
|
|
201
191
|
if (keyUsages == null)
|
|
202
192
|
return undefined;
|
|
203
193
|
// https://datatracker.ietf.org/doc/html/rfc7517#section-4.3
|
|
204
194
|
// > Duplicate key operation values MUST NOT be present in the array.
|
|
205
|
-
const publicOps = new Set(keyUsages.filter(
|
|
195
|
+
const publicOps = new Set(keyUsages.filter(isPublicKeyUsage));
|
|
206
196
|
// @NOTE Translating private key usage into public key usage
|
|
207
197
|
if (keyUsages.includes('sign'))
|
|
208
198
|
publicOps.add('verify');
|
package/dist/key.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key.js","sourceRoot":"","sources":["../src/key.ts"],"names":[],"mappings":"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","sourcesContent":["import { jwkAlgorithms } from './alg.js'\nimport {\n Jwk,\n KeyUsage,\n PUBLIC_KEY_USAGE,\n PrivateJwk,\n PublicJwk,\n PublicKeyUsage,\n hasSharedSecretJwk,\n isEncKeyUsage,\n isPrivateJwk,\n isPublicKeyUsage,\n isSigKeyUsage,\n jwkPubSchema,\n jwkSchema,\n} from './jwk.js'\nimport { VerifyOptions, VerifyResult } from './jwt-verify.js'\nimport { JwtHeader, JwtPayload, SignedJwt } from './jwt.js'\nimport { cachedGetter } from './util.js'\n\nexport type KeyMatchOptions = {\n usage?: KeyUsage\n kid?: string | string[]\n alg?: string | string[]\n}\n\nexport type ActivityCheckOptions = {\n allowRevoked?: boolean\n clockTolerance?: number\n currentDate?: Date\n}\n\nexport abstract class Key<J extends Jwk = Jwk> {\n constructor(readonly jwk: Readonly<J>) {}\n\n @cachedGetter\n get isPrivate(): boolean {\n return isPrivateJwk(this.jwk)\n }\n\n @cachedGetter\n get isSymetric(): boolean {\n return hasSharedSecretJwk(this.jwk)\n }\n\n get privateJwk(): Readonly<PrivateJwk> | undefined {\n if (!this.isPrivate) return undefined\n\n return this.jwk as Readonly<PrivateJwk>\n }\n\n @cachedGetter\n get publicJwk(): Readonly<PublicJwk> | undefined {\n if (this.isSymetric) return undefined\n if (!this.isPrivate) return this.jwk as Readonly<PublicJwk>\n\n const validated = jwkPubSchema.safeParse({\n ...this.jwk,\n d: undefined,\n k: undefined,\n use: undefined,\n key_ops: buildPublicKeyOps(this.keyOps) ?? PUBLIC_KEY_USAGE,\n })\n\n // One reason why the parsing might fail is if key_ops is empty. This check\n // also allows to future proof the code (e.g if another type of private key\n // is added that uses a different property than \"d\" or \"k\" to store its\n // private value).\n if (!validated.success) return undefined\n\n return Object.freeze(validated.data)\n }\n\n @cachedGetter\n get bareJwk(): Readonly<Jwk> | undefined {\n if (this.isSymetric) return undefined\n const { kty, crv, e, n, x, y } = this.jwk as any\n return Object.freeze(jwkSchema.parse({ crv, e, kty, n, x, y }))\n }\n\n /**\n * @note Only defined on public keys\n */\n get use(): 'sig' | 'enc' | undefined {\n return this.jwk.use\n }\n\n get keyOps(): readonly KeyUsage[] | undefined {\n return this.jwk.key_ops\n }\n\n /**\n * The (forced) algorithm to use. If not provided, the key will be usable with\n * any of the algorithms in {@link algorithms}.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc7518#section-3.1 | \"alg\" (Algorithm) Header Parameter Values for JWS}\n */\n get alg() {\n return this.jwk.alg\n }\n\n get kid() {\n return this.jwk.kid\n }\n\n get crv() {\n return (this.jwk as { crv: undefined } | Extract<J, { crv: unknown }>).crv\n }\n\n /**\n * All the algorithms that this key can be used with. If `alg` is provided,\n * this set will only contain that algorithm.\n */\n @cachedGetter\n get algorithms(): readonly string[] {\n return Object.freeze(Array.from(jwkAlgorithms(this.jwk)))\n }\n\n get isRevoked() {\n return this.jwk.revoked != null\n }\n\n isActive(options?: ActivityCheckOptions) {\n if (!options?.allowRevoked && this.isRevoked) return false\n\n const tolerance = options?.clockTolerance ?? 0\n if (tolerance !== Infinity) {\n const now = options?.currentDate?.getTime() ?? Date.now()\n const { exp, nbf } = this.jwk\n\n if (nbf != null && !(now >= nbf * 1e3 - tolerance)) return false\n if (exp != null && !(now < exp * 1e3 + tolerance)) return false\n }\n\n return true\n }\n\n matches(opts: KeyMatchOptions): boolean {\n if (opts.kid != null) {\n const matchesKid = Array.isArray(opts.kid)\n ? this.kid != null && opts.kid.includes(this.kid)\n : this.kid === opts.kid\n if (!matchesKid) return false\n }\n\n if (opts.alg != null) {\n const matchesAlg = Array.isArray(opts.alg)\n ? opts.alg.some((a) => this.algorithms.includes(a))\n : this.algorithms.includes(opts.alg)\n if (!matchesAlg) return false\n }\n\n if (opts.usage != null) {\n const matchesOps =\n this.keyOps == null ||\n this.keyOps.includes(opts.usage) ||\n // @NOTE Because this.jwk represents the private key (typically used for\n // private operations), the public counterpart operations are allowed.\n (opts.usage === 'verify' && this.keyOps.includes('sign')) ||\n (opts.usage === 'encrypt' && this.keyOps.includes('decrypt')) ||\n (opts.usage === 'wrapKey' && this.keyOps.includes('unwrapKey'))\n if (!matchesOps) return false\n\n const matchesUse =\n this.use == null ||\n (this.use === 'sig' && isSigKeyUsage(opts.usage)) ||\n (this.use === 'enc' && isEncKeyUsage(opts.usage))\n if (!matchesUse) return false\n\n // @NOTE This is only relevant when \"key_ops\" and \"use\" are undefined.\n // This line also ensures that when \"opts.usage\" is a private key usage\n // (e.g. \"sign\"), the key is indeed a private key.\n const matchesKeyType = this.isPrivate || isPublicKeyUsage(opts.usage)\n if (!matchesKeyType) return false\n }\n\n return true\n }\n\n /**\n * Create a signed JWT\n */\n abstract createJwt(header: JwtHeader, payload: JwtPayload): Promise<SignedJwt>\n\n /**\n * Verify the signature, headers and payload of a JWT\n *\n * @throws {JwtVerifyError} if the JWT is invalid\n */\n abstract verifyJwt<C extends string = never>(\n token: SignedJwt,\n options?: VerifyOptions<C>,\n ): Promise<VerifyResult<C>>\n}\n\nfunction buildPublicKeyOps(\n keyUsages?: readonly KeyUsage[],\n): PublicKeyUsage[] | undefined {\n if (keyUsages == null) return undefined\n\n // https://datatracker.ietf.org/doc/html/rfc7517#section-4.3\n // > Duplicate key operation values MUST NOT be present in the array.\n const publicOps = new Set(keyUsages.filter(isPublicKeyUsage))\n\n // @NOTE Translating private key usage into public key usage\n if (keyUsages.includes('sign')) publicOps.add('verify')\n if (keyUsages.includes('decrypt')) publicOps.add('encrypt')\n if (keyUsages.includes('unwrapKey')) publicOps.add('wrapKey')\n\n return Array.from(publicOps)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../src/key.ts"],"names":[],"mappings":"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","sourcesContent":["import { jwkAlgorithms } from './alg.js'\nimport {\n Jwk,\n KeyUsage,\n PUBLIC_KEY_USAGE,\n PrivateJwk,\n PublicJwk,\n PublicKeyUsage,\n hasSharedSecretJwk,\n isEncKeyUsage,\n isPrivateJwk,\n isPublicKeyUsage,\n isSigKeyUsage,\n jwkPubSchema,\n jwkSchema,\n} from './jwk.js'\nimport { VerifyOptions, VerifyResult } from './jwt-verify.js'\nimport { JwtHeader, JwtPayload, SignedJwt } from './jwt.js'\nimport { cachedGetter } from './util.js'\n\nexport type KeyMatchOptions = {\n usage?: KeyUsage\n kid?: string | string[]\n alg?: string | string[]\n}\n\nexport type ActivityCheckOptions = {\n allowRevoked?: boolean\n clockTolerance?: number\n currentDate?: Date\n}\n\nexport abstract class Key<J extends Jwk = Jwk> {\n constructor(readonly jwk: Readonly<J>) {}\n\n @cachedGetter\n get isPrivate(): boolean {\n return isPrivateJwk(this.jwk)\n }\n\n @cachedGetter\n get isSymetric(): boolean {\n return hasSharedSecretJwk(this.jwk)\n }\n\n get privateJwk(): Readonly<PrivateJwk> | undefined {\n if (!this.isPrivate) return undefined\n\n return this.jwk as Readonly<PrivateJwk>\n }\n\n @cachedGetter\n get publicJwk(): Readonly<PublicJwk> | undefined {\n if (this.isSymetric) return undefined\n if (!this.isPrivate) return this.jwk as Readonly<PublicJwk>\n\n const validated = jwkPubSchema.safeParse({\n ...this.jwk,\n d: undefined,\n k: undefined,\n use: undefined,\n key_ops: buildPublicKeyOps(this.keyOps) ?? PUBLIC_KEY_USAGE,\n })\n\n // One reason why the parsing might fail is if key_ops is empty. This check\n // also allows to future proof the code (e.g if another type of private key\n // is added that uses a different property than \"d\" or \"k\" to store its\n // private value).\n if (!validated.success) return undefined\n\n return Object.freeze(validated.data)\n }\n\n @cachedGetter\n get bareJwk(): Readonly<Jwk> | undefined {\n if (this.isSymetric) return undefined\n const { kty, crv, e, n, x, y } = this.jwk as any\n return Object.freeze(jwkSchema.parse({ crv, e, kty, n, x, y }))\n }\n\n /**\n * @note Only defined on public keys\n */\n get use(): 'sig' | 'enc' | undefined {\n return this.jwk.use\n }\n\n get keyOps(): readonly KeyUsage[] | undefined {\n return this.jwk.key_ops\n }\n\n /**\n * The (forced) algorithm to use. If not provided, the key will be usable with\n * any of the algorithms in {@link algorithms}.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc7518#section-3.1 | \"alg\" (Algorithm) Header Parameter Values for JWS}\n */\n get alg() {\n return this.jwk.alg\n }\n\n get kid() {\n return this.jwk.kid\n }\n\n get crv() {\n return (this.jwk as { crv: undefined } | Extract<J, { crv: unknown }>).crv\n }\n\n /**\n * All the algorithms that this key can be used with. If `alg` is provided,\n * this set will only contain that algorithm.\n */\n @cachedGetter\n get algorithms(): readonly string[] {\n return Object.freeze(Array.from(jwkAlgorithms(this.jwk)))\n }\n\n get isRevoked() {\n return this.jwk.revoked != null\n }\n\n isActive(options?: ActivityCheckOptions) {\n if (!options?.allowRevoked && this.isRevoked) return false\n\n const tolerance = options?.clockTolerance ?? 0\n if (tolerance !== Infinity) {\n const now = options?.currentDate?.getTime() ?? Date.now()\n const { exp, nbf } = this.jwk\n\n if (nbf != null && !(now >= nbf * 1e3 - tolerance)) return false\n if (exp != null && !(now < exp * 1e3 + tolerance)) return false\n }\n\n return true\n }\n\n matches(opts: KeyMatchOptions): boolean {\n if (opts.kid != null) {\n const matchesKid = Array.isArray(opts.kid)\n ? this.kid != null && opts.kid.includes(this.kid)\n : this.kid === opts.kid\n if (!matchesKid) return false\n }\n\n if (opts.alg != null) {\n const matchesAlg = Array.isArray(opts.alg)\n ? opts.alg.some((a) => this.algorithms.includes(a))\n : this.algorithms.includes(opts.alg)\n if (!matchesAlg) return false\n }\n\n if (opts.usage != null) {\n const matchesOps =\n this.keyOps == null ||\n this.keyOps.includes(opts.usage) ||\n // @NOTE Because this.jwk represents the private key (typically used for\n // private operations), the public counterpart operations are allowed.\n (opts.usage === 'verify' && this.keyOps.includes('sign')) ||\n (opts.usage === 'encrypt' && this.keyOps.includes('decrypt')) ||\n (opts.usage === 'wrapKey' && this.keyOps.includes('unwrapKey'))\n if (!matchesOps) return false\n\n const matchesUse =\n this.use == null ||\n (this.use === 'sig' && isSigKeyUsage(opts.usage)) ||\n (this.use === 'enc' && isEncKeyUsage(opts.usage))\n if (!matchesUse) return false\n\n // @NOTE This is only relevant when \"key_ops\" and \"use\" are undefined.\n // This line also ensures that when \"opts.usage\" is a private key usage\n // (e.g. \"sign\"), the key is indeed a private key.\n const matchesKeyType = this.isPrivate || isPublicKeyUsage(opts.usage)\n if (!matchesKeyType) return false\n }\n\n return true\n }\n\n /**\n * Create a signed JWT\n */\n abstract createJwt(header: JwtHeader, payload: JwtPayload): Promise<SignedJwt>\n\n /**\n * Verify the signature, headers and payload of a JWT\n *\n * @throws {JwtVerifyError} if the JWT is invalid\n */\n abstract verifyJwt<C extends string = never>(\n token: SignedJwt,\n options?: VerifyOptions<C>,\n ): Promise<VerifyResult<C>>\n}\n\nfunction buildPublicKeyOps(\n keyUsages?: readonly KeyUsage[],\n): PublicKeyUsage[] | undefined {\n if (keyUsages == null) return undefined\n\n // https://datatracker.ietf.org/doc/html/rfc7517#section-4.3\n // > Duplicate key operation values MUST NOT be present in the array.\n const publicOps = new Set(keyUsages.filter(isPublicKeyUsage))\n\n // @NOTE Translating private key usage into public key usage\n if (keyUsages.includes('sign')) publicOps.add('verify')\n if (keyUsages.includes('decrypt')) publicOps.add('encrypt')\n if (keyUsages.includes('unwrapKey')) publicOps.add('wrapKey')\n\n return Array.from(publicOps)\n}\n"]}
|