@yielded/jose 0.1.0-beta.28 → 0.1.0-beta.30

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/Jwk.d.mts CHANGED
@@ -84,6 +84,85 @@ export declare const SecretJwk: Schema.Struct<{
84
84
  readonly k: Schema.String;
85
85
  }>;
86
86
  export type SecretJwk = typeof SecretJwk.Type;
87
+ export declare const GenerateKeyPairInput: Schema.Union<readonly [Schema.Struct<{
88
+ readonly algorithm: Schema.Literals<readonly ["RS256", "PS256"]>;
89
+ readonly modulusLength: Schema.optionalKey<Schema.Literals<readonly [2048, 3072, 4096]>>;
90
+ readonly kid: Schema.optionalKey<Schema.String>;
91
+ }>, Schema.Struct<{
92
+ readonly algorithm: Schema.Literals<readonly ["ES256", "EdDSA"]>;
93
+ readonly kid: Schema.optionalKey<Schema.String>;
94
+ }>]>;
95
+ export type GenerateKeyPairInput = typeof GenerateKeyPairInput.Type;
96
+ export declare const GeneratedKeyPair: Schema.Struct<{
97
+ readonly publicKey: Schema.Union<readonly [Schema.Struct<{
98
+ readonly kid: Schema.optionalKey<Schema.String>;
99
+ readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
100
+ readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
101
+ readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
102
+ readonly kty: Schema.Literal<"RSA">;
103
+ readonly n: Schema.String;
104
+ readonly e: Schema.String;
105
+ readonly d: Schema.optionalKey<Schema.Never>;
106
+ readonly k: Schema.optionalKey<Schema.Never>;
107
+ }>, Schema.Struct<{
108
+ readonly kid: Schema.optionalKey<Schema.String>;
109
+ readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
110
+ readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
111
+ readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
112
+ readonly kty: Schema.Literal<"EC">;
113
+ readonly crv: Schema.Literal<"P-256">;
114
+ readonly x: Schema.String;
115
+ readonly y: Schema.String;
116
+ readonly d: Schema.optionalKey<Schema.Never>;
117
+ readonly k: Schema.optionalKey<Schema.Never>;
118
+ }>, Schema.Struct<{
119
+ readonly kid: Schema.optionalKey<Schema.String>;
120
+ readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
121
+ readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
122
+ readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
123
+ readonly kty: Schema.Literal<"OKP">;
124
+ readonly crv: Schema.Literal<"Ed25519">;
125
+ readonly x: Schema.String;
126
+ readonly d: Schema.optionalKey<Schema.Never>;
127
+ readonly k: Schema.optionalKey<Schema.Never>;
128
+ }>]>;
129
+ readonly privateKey: Schema.Redacted<Schema.Union<readonly [Schema.Struct<{
130
+ readonly kid: Schema.optionalKey<Schema.String>;
131
+ readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
132
+ readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
133
+ readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
134
+ readonly kty: Schema.Literal<"RSA">;
135
+ readonly n: Schema.String;
136
+ readonly e: Schema.String;
137
+ readonly d: Schema.String;
138
+ readonly p: Schema.String;
139
+ readonly q: Schema.String;
140
+ readonly dp: Schema.String;
141
+ readonly dq: Schema.String;
142
+ readonly qi: Schema.String;
143
+ readonly oth: Schema.optionalKey<Schema.Never>;
144
+ }>, Schema.Struct<{
145
+ readonly kid: Schema.optionalKey<Schema.String>;
146
+ readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
147
+ readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
148
+ readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
149
+ readonly kty: Schema.Literal<"EC">;
150
+ readonly crv: Schema.Literal<"P-256">;
151
+ readonly x: Schema.String;
152
+ readonly y: Schema.String;
153
+ readonly d: Schema.String;
154
+ }>, Schema.Struct<{
155
+ readonly kid: Schema.optionalKey<Schema.String>;
156
+ readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
157
+ readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
158
+ readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
159
+ readonly kty: Schema.Literal<"OKP">;
160
+ readonly crv: Schema.Literal<"Ed25519">;
161
+ readonly x: Schema.String;
162
+ readonly d: Schema.String;
163
+ }>]>>;
164
+ }>;
165
+ export type GeneratedKeyPair = typeof GeneratedKeyPair.Type;
87
166
  /** Validated, algorithm-bound key snapshots. Private material remains Redacted. */
88
167
  export interface PublicKey {
89
168
  readonly _tag: "PublicKey";
@@ -105,6 +184,83 @@ export interface SecretKey {
105
184
  }
106
185
  export type SigningKey = PrivateKey | SecretKey;
107
186
  export type VerificationKey = PublicKey | SecretKey;
187
+ /** Generate typed signing JWKs through the selected crypto backend. */
188
+ export declare const generateKeyPair: (input: {
189
+ readonly algorithm: "PS256" | "RS256";
190
+ readonly modulusLength?: 2048 | 3072 | 4096;
191
+ readonly kid?: string;
192
+ } | {
193
+ readonly algorithm: "ES256" | "EdDSA";
194
+ readonly kid?: string;
195
+ }) => Effect.Effect<{
196
+ readonly publicKey: {
197
+ readonly kid?: string;
198
+ readonly alg?: string;
199
+ readonly use?: "enc" | "sig";
200
+ readonly key_ops?: readonly string[];
201
+ readonly kty: "RSA";
202
+ readonly n: string;
203
+ readonly e: string;
204
+ readonly d?: never;
205
+ readonly k?: never;
206
+ } | {
207
+ readonly kid?: string;
208
+ readonly alg?: string;
209
+ readonly use?: "enc" | "sig";
210
+ readonly key_ops?: readonly string[];
211
+ readonly kty: "EC";
212
+ readonly crv: "P-256";
213
+ readonly x: string;
214
+ readonly y: string;
215
+ readonly d?: never;
216
+ readonly k?: never;
217
+ } | {
218
+ readonly kid?: string;
219
+ readonly alg?: string;
220
+ readonly use?: "enc" | "sig";
221
+ readonly key_ops?: readonly string[];
222
+ readonly kty: "OKP";
223
+ readonly crv: "Ed25519";
224
+ readonly x: string;
225
+ readonly d?: never;
226
+ readonly k?: never;
227
+ };
228
+ readonly privateKey: Redacted.Redacted<{
229
+ readonly kid?: string;
230
+ readonly alg?: string;
231
+ readonly use?: "enc" | "sig";
232
+ readonly key_ops?: readonly string[];
233
+ readonly kty: "RSA";
234
+ readonly n: string;
235
+ readonly e: string;
236
+ readonly d: string;
237
+ readonly p: string;
238
+ readonly q: string;
239
+ readonly dp: string;
240
+ readonly dq: string;
241
+ readonly qi: string;
242
+ readonly oth?: never;
243
+ } | {
244
+ readonly kid?: string;
245
+ readonly alg?: string;
246
+ readonly use?: "enc" | "sig";
247
+ readonly key_ops?: readonly string[];
248
+ readonly kty: "EC";
249
+ readonly crv: "P-256";
250
+ readonly x: string;
251
+ readonly y: string;
252
+ readonly d: string;
253
+ } | {
254
+ readonly kid?: string;
255
+ readonly alg?: string;
256
+ readonly use?: "enc" | "sig";
257
+ readonly key_ops?: readonly string[];
258
+ readonly kty: "OKP";
259
+ readonly crv: "Ed25519";
260
+ readonly x: string;
261
+ readonly d: string;
262
+ }>;
263
+ }, InvalidKey | import("@yielded/crypto/Errors").OperationError, Signature$1.Signature>;
108
264
  export declare const importPublic: (input: unknown, selected: "ES256" | "EdDSA" | "PS256" | "RS256") => Effect.Effect<Readonly<{
109
265
  _tag: "PublicKey";
110
266
  algorithm: "ES256" | "EdDSA" | "PS256" | "RS256";
package/dist/Jwk.mjs CHANGED
@@ -4,6 +4,7 @@ import { decode, reveal } from "./internal/encoding.mjs";
4
4
  import { detach, jwk } from "./internal/keyInput.mjs";
5
5
  import { Effect, Redacted, Schema } from "effect";
6
6
  import * as Signature$1 from "@yielded/crypto/Signature";
7
+ import { Base64Url } from "effect/encoding";
7
8
  //#region src/Jwk.ts
8
9
  const AsymmetricAlgorithm = Schema.Literals([
9
10
  "RS256",
@@ -88,6 +89,90 @@ const SecretJwk = Schema.Struct({
88
89
  kty: Schema.Literal("oct"),
89
90
  k: encodedBytes
90
91
  });
92
+ const GenerateKeyPairInput = Schema.Union([Schema.Struct({
93
+ algorithm: Schema.Literals(["RS256", "PS256"]),
94
+ modulusLength: Schema.optionalKey(Signature$1.RsaModulusLength),
95
+ kid: metadata.kid
96
+ }), Schema.Struct({
97
+ algorithm: Schema.Literals(["ES256", "EdDSA"]),
98
+ kid: metadata.kid
99
+ })]);
100
+ const GeneratedKeyPair = Schema.Struct({
101
+ publicKey: PublicJwk,
102
+ privateKey: Schema.Redacted(PrivateJwk, { disallowJsonEncode: true })
103
+ });
104
+ /** Generate typed signing JWKs through the selected crypto backend. */
105
+ const generateKeyPair = Effect.fnUntraced(function* (input) {
106
+ const value = yield* Schema.decodeEffect(GenerateKeyPairInput)(input).pipe(Effect.mapError(() => InvalidKey.make({})));
107
+ const signatures = yield* Signature$1.Signature;
108
+ return yield* Effect.acquireUseRelease(signatures.generateKeyPair({
109
+ algorithm: algorithms[value.algorithm],
110
+ ..."modulusLength" in value ? { modulusLength: value.modulusLength } : {}
111
+ }), (pair) => Effect.sync(() => {
112
+ const parameters = Redacted.value(pair.privateKey);
113
+ const meta = {
114
+ alg: value.algorithm,
115
+ use: "sig",
116
+ ...value.kid === void 0 ? {} : { kid: value.kid }
117
+ };
118
+ switch (parameters.algorithm) {
119
+ case "RSASSA-PKCS1-v1_5-SHA256":
120
+ case "RSA-PSS-SHA256": {
121
+ const publicKey = {
122
+ ...meta,
123
+ kty: "RSA",
124
+ n: Base64Url.encode(parameters.n),
125
+ e: Base64Url.encode(parameters.e)
126
+ };
127
+ return {
128
+ publicKey,
129
+ privateKey: Redacted.make({
130
+ ...publicKey,
131
+ d: Base64Url.encode(parameters.d),
132
+ p: Base64Url.encode(parameters.p),
133
+ q: Base64Url.encode(parameters.q),
134
+ dp: Base64Url.encode(parameters.dp),
135
+ dq: Base64Url.encode(parameters.dq),
136
+ qi: Base64Url.encode(parameters.qi)
137
+ })
138
+ };
139
+ }
140
+ case "ECDSA-P256-SHA256": {
141
+ const publicKey = {
142
+ ...meta,
143
+ kty: "EC",
144
+ crv: "P-256",
145
+ x: Base64Url.encode(parameters.x),
146
+ y: Base64Url.encode(parameters.y)
147
+ };
148
+ return {
149
+ publicKey,
150
+ privateKey: Redacted.make({
151
+ ...publicKey,
152
+ d: Base64Url.encode(parameters.d)
153
+ })
154
+ };
155
+ }
156
+ case "Ed25519": {
157
+ const publicKey = {
158
+ ...meta,
159
+ kty: "OKP",
160
+ crv: "Ed25519",
161
+ x: Base64Url.encode(parameters.x)
162
+ };
163
+ return {
164
+ publicKey,
165
+ privateKey: Redacted.make({
166
+ ...publicKey,
167
+ d: Base64Url.encode(parameters.d)
168
+ })
169
+ };
170
+ }
171
+ }
172
+ }), (pair) => Effect.sync(() => {
173
+ for (const part of Object.values(Redacted.value(pair.privateKey))) if (typeof part !== "string") part.fill(0);
174
+ }));
175
+ });
91
176
  const read = (schema, input) => Effect.try({
92
177
  try: () => jwk(input),
93
178
  catch: () => InvalidKey.make({})
@@ -190,6 +275,6 @@ const exportPrivate = Effect.fnUntraced(function* (key) {
190
275
  return Redacted.make(yield* read(Schema.Union([PrivateJwk, SecretJwk]), value));
191
276
  });
192
277
  //#endregion
193
- export { Algorithm, AsymmetricAlgorithm, PrivateJwk, PublicJwk, SecretJwk, exportPrivate, exportPublic, importPrivate, importPublic, importSecret };
278
+ export { Algorithm, AsymmetricAlgorithm, GenerateKeyPairInput, GeneratedKeyPair, PrivateJwk, PublicJwk, SecretJwk, exportPrivate, exportPublic, generateKeyPair, importPrivate, importPublic, importSecret };
194
279
 
195
280
  //# sourceMappingURL=Jwk.mjs.map
package/dist/Jwk.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Jwk.mjs","names":["KeyInput.jwk","KeyInput.detach","Signature"],"sources":["../src/Jwk.ts"],"sourcesContent":["import * as Signature from \"@yielded/crypto/Signature\";\nimport { Effect, Redacted, Schema } from \"effect\";\n\nimport { InvalidKey } from \"./Errors\";\nimport { algorithms } from \"./internal/algorithms\";\nimport { decode, reveal } from \"./internal/encoding\";\nimport * as KeyInput from \"./internal/keyInput\";\n\nexport const AsymmetricAlgorithm = Schema.Literals([\"RS256\", \"PS256\", \"ES256\", \"EdDSA\"]);\nexport type AsymmetricAlgorithm = typeof AsymmetricAlgorithm.Type;\nexport const Algorithm = Schema.Literals([\"HS256\", \"RS256\", \"PS256\", \"ES256\", \"EdDSA\"]);\nexport type Algorithm = typeof Algorithm.Type;\n\nconst encodedBytes = Schema.String.check(\n Schema.isPattern(/^[A-Za-z0-9_-]+$/),\n Schema.isMaxLength(16384),\n);\n\nconst operations = Schema.Array(Schema.NonEmptyString).check(\n Schema.isMaxLength(KeyInput.maxArrayLength),\n Schema.makeFilter((values) => new Set(values).size === values.length),\n);\n\nconst metadata = {\n kid: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(256))),\n alg: Schema.optionalKey(Schema.NonEmptyString),\n use: Schema.optionalKey(Schema.Literals([\"sig\", \"enc\"])),\n key_ops: Schema.optionalKey(operations),\n};\n\nconst rsa = { ...metadata, kty: Schema.Literal(\"RSA\"), n: encodedBytes, e: encodedBytes };\n\nconst ec = {\n ...metadata,\n kty: Schema.Literal(\"EC\"),\n crv: Schema.Literal(\"P-256\"),\n x: encodedBytes,\n y: encodedBytes,\n};\n\nconst okp = {\n ...metadata,\n kty: Schema.Literal(\"OKP\"),\n crv: Schema.Literal(\"Ed25519\"),\n x: encodedBytes,\n};\n\nconst noSecret = { d: Schema.optionalKey(Schema.Never), k: Schema.optionalKey(Schema.Never) };\n\nexport const PublicJwk = Schema.Union([\n Schema.Struct({ ...rsa, ...noSecret }),\n Schema.Struct({ ...ec, ...noSecret }),\n Schema.Struct({ ...okp, ...noSecret }),\n]);\n\nexport type PublicJwk = typeof PublicJwk.Type;\n\nexport const PrivateJwk = Schema.Union([\n Schema.Struct({\n ...rsa,\n d: encodedBytes,\n p: encodedBytes,\n q: encodedBytes,\n dp: encodedBytes,\n dq: encodedBytes,\n qi: encodedBytes,\n oth: Schema.optionalKey(Schema.Never),\n }),\n Schema.Struct({ ...ec, d: encodedBytes }),\n Schema.Struct({ ...okp, d: encodedBytes }),\n]);\n\nexport type PrivateJwk = typeof PrivateJwk.Type;\n\nexport const SecretJwk = Schema.Struct({\n ...metadata,\n kty: Schema.Literal(\"oct\"),\n k: encodedBytes,\n});\n\nexport type SecretJwk = typeof SecretJwk.Type;\n\n/** Validated, algorithm-bound key snapshots. Private material remains Redacted. */\nexport interface PublicKey {\n readonly _tag: \"PublicKey\";\n readonly algorithm: AsymmetricAlgorithm;\n readonly jwk: PublicJwk;\n readonly material: Uint8Array;\n}\n\nexport interface PrivateKey {\n readonly _tag: \"PrivateKey\";\n readonly algorithm: AsymmetricAlgorithm;\n readonly jwk: Redacted.Redacted<PrivateJwk>;\n readonly material: Redacted.Redacted<Uint8Array>;\n}\n\nexport interface SecretKey {\n readonly _tag: \"SecretKey\";\n readonly algorithm: \"HS256\" | \"dir\";\n readonly jwk: Redacted.Redacted<SecretJwk>;\n readonly material: Redacted.Redacted<Uint8Array>;\n}\n\nexport type SigningKey = PrivateKey | SecretKey;\nexport type VerificationKey = PublicKey | SecretKey;\n\nconst read = <S extends Schema.Constraint>(schema: S, input: unknown) =>\n Effect.try({\n try: () => KeyInput.jwk(input),\n catch: () => InvalidKey.make({}),\n }).pipe(\n Effect.flatMap(Effect.fromResult),\n Effect.flatMap((captured) =>\n Schema.decodeUnknownEffect(schema)(captured, { reportInput: false }).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n ),\n ),\n Effect.map(KeyInput.detach),\n );\n\nconst bytes = (value: string) => decode(value).pipe(Effect.mapError(() => InvalidKey.make({})));\n\nconst snapshot = <A extends PublicJwk | PrivateJwk | SecretJwk>(jwk: A): A => {\n if (jwk.key_ops !== undefined) Object.freeze(jwk.key_ops);\n\n return Object.freeze(jwk);\n};\n\nconst publicParameters = Effect.fnUntraced(function* (\n jwk: PublicJwk | PrivateJwk,\n algorithm: AsymmetricAlgorithm,\n): Effect.fn.Return<Signature.PublicKeyParameters, InvalidKey> {\n if (jwk.alg !== undefined && jwk.alg !== algorithm) return yield* InvalidKey.make({});\n switch (jwk.kty) {\n case \"EC\":\n if (algorithm !== \"ES256\") return yield* InvalidKey.make({});\n\n return { algorithm: \"ECDSA-P256-SHA256\", x: yield* bytes(jwk.x), y: yield* bytes(jwk.y) };\n case \"OKP\":\n if (algorithm !== \"EdDSA\") return yield* InvalidKey.make({});\n\n return { algorithm: \"Ed25519\", x: yield* bytes(jwk.x) };\n case \"RSA\":\n if (algorithm !== \"RS256\" && algorithm !== \"PS256\") return yield* InvalidKey.make({});\n\n return { algorithm: algorithms[algorithm], n: yield* bytes(jwk.n), e: yield* bytes(jwk.e) };\n }\n});\n\nexport const importPublic = Effect.fnUntraced(function* (\n input: unknown,\n selected: AsymmetricAlgorithm,\n) {\n const algorithm = yield* read(AsymmetricAlgorithm, selected);\n const jwk = yield* read(PublicJwk, input);\n const parameters = yield* publicParameters(jwk, algorithm);\n const signatures = yield* Signature.Signature;\n\n const material = yield* signatures\n .encodePublicKey(parameters)\n .pipe(Effect.catchTag(\"CryptoInvalidInput\", () => InvalidKey.make({})));\n\n return Object.freeze({\n _tag: \"PublicKey\",\n algorithm,\n jwk: snapshot(jwk),\n material,\n }) satisfies PublicKey;\n});\n\nexport const importPrivate = Effect.fnUntraced(function* (\n input: Redacted.Redacted<unknown>,\n selected: AsymmetricAlgorithm,\n) {\n const algorithm = yield* read(AsymmetricAlgorithm, selected);\n\n const jwk = yield* read(\n PrivateJwk,\n yield* reveal(input).pipe(Effect.mapError(() => InvalidKey.make({}))),\n );\n\n const publicPart = yield* publicParameters(jwk, algorithm);\n const d = yield* bytes(jwk.d);\n\n const parameters = yield* read(Signature.PrivateKeyParameters, {\n ...publicPart,\n d,\n ...(jwk.kty === \"RSA\"\n ? {\n p: yield* bytes(jwk.p),\n q: yield* bytes(jwk.q),\n dp: yield* bytes(jwk.dp),\n dq: yield* bytes(jwk.dq),\n qi: yield* bytes(jwk.qi),\n }\n : {}),\n });\n\n const signatures = yield* Signature.Signature;\n\n const material = yield* signatures.encodePrivateKey(Redacted.make(parameters)).pipe(\n Effect.catchTag(\"CryptoInvalidInput\", () => InvalidKey.make({})),\n Effect.ensuring(\n Effect.sync(() => {\n parameters.d.fill(0);\n if (\"p\" in parameters)\n for (const part of [\n parameters.p,\n parameters.q,\n parameters.dp,\n parameters.dq,\n parameters.qi,\n ])\n part.fill(0);\n }),\n ),\n );\n\n return Object.freeze({\n _tag: \"PrivateKey\",\n algorithm,\n jwk: Redacted.make(snapshot(jwk)),\n material,\n }) satisfies PrivateKey;\n});\n\nexport const importSecret = Effect.fnUntraced(function* (\n input: Redacted.Redacted<unknown>,\n selected: \"HS256\" | \"dir\",\n) {\n const algorithm = yield* read(Schema.Literals([\"HS256\", \"dir\"]), selected);\n\n const jwk = yield* read(\n SecretJwk,\n yield* reveal(input).pipe(Effect.mapError(() => InvalidKey.make({}))),\n );\n\n const material = yield* bytes(jwk.k);\n\n if (\n (jwk.alg !== undefined && jwk.alg !== algorithm) ||\n material.length < 32 ||\n (algorithm === \"dir\" && material.length !== 32)\n ) {\n material.fill(0);\n\n return yield* InvalidKey.make({});\n }\n\n return Object.freeze({\n _tag: \"SecretKey\",\n algorithm,\n jwk: Redacted.make(snapshot(jwk)),\n material: Redacted.make(material),\n }) satisfies SecretKey;\n});\n\nexport const exportPublic = Effect.fnUntraced(function* (key: PublicKey) {\n return yield* read(PublicJwk, key.jwk);\n});\n\nexport const exportPrivate = Effect.fnUntraced(function* (key: PrivateKey | SecretKey) {\n const value = yield* reveal<PrivateJwk | SecretJwk>(key.jwk).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n );\n\n return Redacted.make(yield* read(Schema.Union([PrivateJwk, SecretJwk]), value));\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Jwk.mjs","names":["Signature","KeyInput.jwk","KeyInput.detach"],"sources":["../src/Jwk.ts"],"sourcesContent":["import * as Signature from \"@yielded/crypto/Signature\";\nimport { Effect, Redacted, Schema } from \"effect\";\nimport { Base64Url } from \"effect/encoding\";\n\nimport { InvalidKey } from \"./Errors\";\nimport { algorithms } from \"./internal/algorithms\";\nimport { decode, reveal } from \"./internal/encoding\";\nimport * as KeyInput from \"./internal/keyInput\";\n\nexport const AsymmetricAlgorithm = Schema.Literals([\"RS256\", \"PS256\", \"ES256\", \"EdDSA\"]);\nexport type AsymmetricAlgorithm = typeof AsymmetricAlgorithm.Type;\nexport const Algorithm = Schema.Literals([\"HS256\", \"RS256\", \"PS256\", \"ES256\", \"EdDSA\"]);\nexport type Algorithm = typeof Algorithm.Type;\n\nconst encodedBytes = Schema.String.check(\n Schema.isPattern(/^[A-Za-z0-9_-]+$/),\n Schema.isMaxLength(16384),\n);\n\nconst operations = Schema.Array(Schema.NonEmptyString).check(\n Schema.isMaxLength(KeyInput.maxArrayLength),\n Schema.makeFilter((values) => new Set(values).size === values.length),\n);\n\nconst metadata = {\n kid: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(256))),\n alg: Schema.optionalKey(Schema.NonEmptyString),\n use: Schema.optionalKey(Schema.Literals([\"sig\", \"enc\"])),\n key_ops: Schema.optionalKey(operations),\n};\n\nconst rsa = { ...metadata, kty: Schema.Literal(\"RSA\"), n: encodedBytes, e: encodedBytes };\n\nconst ec = {\n ...metadata,\n kty: Schema.Literal(\"EC\"),\n crv: Schema.Literal(\"P-256\"),\n x: encodedBytes,\n y: encodedBytes,\n};\n\nconst okp = {\n ...metadata,\n kty: Schema.Literal(\"OKP\"),\n crv: Schema.Literal(\"Ed25519\"),\n x: encodedBytes,\n};\n\nconst noSecret = { d: Schema.optionalKey(Schema.Never), k: Schema.optionalKey(Schema.Never) };\n\nexport const PublicJwk = Schema.Union([\n Schema.Struct({ ...rsa, ...noSecret }),\n Schema.Struct({ ...ec, ...noSecret }),\n Schema.Struct({ ...okp, ...noSecret }),\n]);\n\nexport type PublicJwk = typeof PublicJwk.Type;\n\nexport const PrivateJwk = Schema.Union([\n Schema.Struct({\n ...rsa,\n d: encodedBytes,\n p: encodedBytes,\n q: encodedBytes,\n dp: encodedBytes,\n dq: encodedBytes,\n qi: encodedBytes,\n oth: Schema.optionalKey(Schema.Never),\n }),\n Schema.Struct({ ...ec, d: encodedBytes }),\n Schema.Struct({ ...okp, d: encodedBytes }),\n]);\n\nexport type PrivateJwk = typeof PrivateJwk.Type;\n\nexport const SecretJwk = Schema.Struct({\n ...metadata,\n kty: Schema.Literal(\"oct\"),\n k: encodedBytes,\n});\n\nexport type SecretJwk = typeof SecretJwk.Type;\n\nexport const GenerateKeyPairInput = Schema.Union([\n Schema.Struct({\n algorithm: Schema.Literals([\"RS256\", \"PS256\"]),\n modulusLength: Schema.optionalKey(Signature.RsaModulusLength),\n kid: metadata.kid,\n }),\n Schema.Struct({ algorithm: Schema.Literals([\"ES256\", \"EdDSA\"]), kid: metadata.kid }),\n]);\n\nexport type GenerateKeyPairInput = typeof GenerateKeyPairInput.Type;\n\nexport const GeneratedKeyPair = Schema.Struct({\n publicKey: PublicJwk,\n privateKey: Schema.Redacted(PrivateJwk, { disallowJsonEncode: true }),\n});\n\nexport type GeneratedKeyPair = typeof GeneratedKeyPair.Type;\n\n/** Validated, algorithm-bound key snapshots. Private material remains Redacted. */\nexport interface PublicKey {\n readonly _tag: \"PublicKey\";\n readonly algorithm: AsymmetricAlgorithm;\n readonly jwk: PublicJwk;\n readonly material: Uint8Array;\n}\n\nexport interface PrivateKey {\n readonly _tag: \"PrivateKey\";\n readonly algorithm: AsymmetricAlgorithm;\n readonly jwk: Redacted.Redacted<PrivateJwk>;\n readonly material: Redacted.Redacted<Uint8Array>;\n}\n\nexport interface SecretKey {\n readonly _tag: \"SecretKey\";\n readonly algorithm: \"HS256\" | \"dir\";\n readonly jwk: Redacted.Redacted<SecretJwk>;\n readonly material: Redacted.Redacted<Uint8Array>;\n}\n\nexport type SigningKey = PrivateKey | SecretKey;\nexport type VerificationKey = PublicKey | SecretKey;\n\n/** Generate typed signing JWKs through the selected crypto backend. */\nexport const generateKeyPair = Effect.fnUntraced(function* (input: GenerateKeyPairInput) {\n const value = yield* Schema.decodeEffect(GenerateKeyPairInput)(input).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n );\n\n const signatures = yield* Signature.Signature;\n\n return yield* Effect.acquireUseRelease(\n signatures.generateKeyPair({\n algorithm: algorithms[value.algorithm],\n ...(\"modulusLength\" in value ? { modulusLength: value.modulusLength } : {}),\n }),\n (pair) =>\n Effect.sync((): GeneratedKeyPair => {\n const parameters = Redacted.value(pair.privateKey);\n\n const meta = {\n alg: value.algorithm,\n use: \"sig\" as const,\n ...(value.kid === undefined ? {} : { kid: value.kid }),\n };\n\n switch (parameters.algorithm) {\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n case \"RSA-PSS-SHA256\": {\n const publicKey = {\n ...meta,\n kty: \"RSA\" as const,\n n: Base64Url.encode(parameters.n),\n e: Base64Url.encode(parameters.e),\n };\n\n return {\n publicKey,\n privateKey: Redacted.make({\n ...publicKey,\n d: Base64Url.encode(parameters.d),\n p: Base64Url.encode(parameters.p),\n q: Base64Url.encode(parameters.q),\n dp: Base64Url.encode(parameters.dp),\n dq: Base64Url.encode(parameters.dq),\n qi: Base64Url.encode(parameters.qi),\n }),\n };\n }\n case \"ECDSA-P256-SHA256\": {\n const publicKey = {\n ...meta,\n kty: \"EC\" as const,\n crv: \"P-256\" as const,\n x: Base64Url.encode(parameters.x),\n y: Base64Url.encode(parameters.y),\n };\n\n return {\n publicKey,\n privateKey: Redacted.make({ ...publicKey, d: Base64Url.encode(parameters.d) }),\n };\n }\n case \"Ed25519\": {\n const publicKey = {\n ...meta,\n kty: \"OKP\" as const,\n crv: \"Ed25519\" as const,\n x: Base64Url.encode(parameters.x),\n };\n\n return {\n publicKey,\n privateKey: Redacted.make({ ...publicKey, d: Base64Url.encode(parameters.d) }),\n };\n }\n }\n }),\n (pair) =>\n Effect.sync(() => {\n for (const part of Object.values(Redacted.value(pair.privateKey))) {\n if (typeof part !== \"string\") part.fill(0);\n }\n }),\n );\n});\n\nconst read = <S extends Schema.Constraint>(schema: S, input: unknown) =>\n Effect.try({\n try: () => KeyInput.jwk(input),\n catch: () => InvalidKey.make({}),\n }).pipe(\n Effect.flatMap(Effect.fromResult),\n Effect.flatMap((captured) =>\n Schema.decodeUnknownEffect(schema)(captured, { reportInput: false }).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n ),\n ),\n Effect.map(KeyInput.detach),\n );\n\nconst bytes = (value: string) => decode(value).pipe(Effect.mapError(() => InvalidKey.make({})));\n\nconst snapshot = <A extends PublicJwk | PrivateJwk | SecretJwk>(jwk: A): A => {\n if (jwk.key_ops !== undefined) Object.freeze(jwk.key_ops);\n\n return Object.freeze(jwk);\n};\n\nconst publicParameters = Effect.fnUntraced(function* (\n jwk: PublicJwk | PrivateJwk,\n algorithm: AsymmetricAlgorithm,\n): Effect.fn.Return<Signature.PublicKeyParameters, InvalidKey> {\n if (jwk.alg !== undefined && jwk.alg !== algorithm) return yield* InvalidKey.make({});\n switch (jwk.kty) {\n case \"EC\":\n if (algorithm !== \"ES256\") return yield* InvalidKey.make({});\n\n return { algorithm: \"ECDSA-P256-SHA256\", x: yield* bytes(jwk.x), y: yield* bytes(jwk.y) };\n case \"OKP\":\n if (algorithm !== \"EdDSA\") return yield* InvalidKey.make({});\n\n return { algorithm: \"Ed25519\", x: yield* bytes(jwk.x) };\n case \"RSA\":\n if (algorithm !== \"RS256\" && algorithm !== \"PS256\") return yield* InvalidKey.make({});\n\n return { algorithm: algorithms[algorithm], n: yield* bytes(jwk.n), e: yield* bytes(jwk.e) };\n }\n});\n\nexport const importPublic = Effect.fnUntraced(function* (\n input: unknown,\n selected: AsymmetricAlgorithm,\n) {\n const algorithm = yield* read(AsymmetricAlgorithm, selected);\n const jwk = yield* read(PublicJwk, input);\n const parameters = yield* publicParameters(jwk, algorithm);\n const signatures = yield* Signature.Signature;\n\n const material = yield* signatures\n .encodePublicKey(parameters)\n .pipe(Effect.catchTag(\"CryptoInvalidInput\", () => InvalidKey.make({})));\n\n return Object.freeze({\n _tag: \"PublicKey\",\n algorithm,\n jwk: snapshot(jwk),\n material,\n }) satisfies PublicKey;\n});\n\nexport const importPrivate = Effect.fnUntraced(function* (\n input: Redacted.Redacted<unknown>,\n selected: AsymmetricAlgorithm,\n) {\n const algorithm = yield* read(AsymmetricAlgorithm, selected);\n\n const jwk = yield* read(\n PrivateJwk,\n yield* reveal(input).pipe(Effect.mapError(() => InvalidKey.make({}))),\n );\n\n const publicPart = yield* publicParameters(jwk, algorithm);\n const d = yield* bytes(jwk.d);\n\n const parameters = yield* read(Signature.PrivateKeyParameters, {\n ...publicPart,\n d,\n ...(jwk.kty === \"RSA\"\n ? {\n p: yield* bytes(jwk.p),\n q: yield* bytes(jwk.q),\n dp: yield* bytes(jwk.dp),\n dq: yield* bytes(jwk.dq),\n qi: yield* bytes(jwk.qi),\n }\n : {}),\n });\n\n const signatures = yield* Signature.Signature;\n\n const material = yield* signatures.encodePrivateKey(Redacted.make(parameters)).pipe(\n Effect.catchTag(\"CryptoInvalidInput\", () => InvalidKey.make({})),\n Effect.ensuring(\n Effect.sync(() => {\n parameters.d.fill(0);\n if (\"p\" in parameters)\n for (const part of [\n parameters.p,\n parameters.q,\n parameters.dp,\n parameters.dq,\n parameters.qi,\n ])\n part.fill(0);\n }),\n ),\n );\n\n return Object.freeze({\n _tag: \"PrivateKey\",\n algorithm,\n jwk: Redacted.make(snapshot(jwk)),\n material,\n }) satisfies PrivateKey;\n});\n\nexport const importSecret = Effect.fnUntraced(function* (\n input: Redacted.Redacted<unknown>,\n selected: \"HS256\" | \"dir\",\n) {\n const algorithm = yield* read(Schema.Literals([\"HS256\", \"dir\"]), selected);\n\n const jwk = yield* read(\n SecretJwk,\n yield* reveal(input).pipe(Effect.mapError(() => InvalidKey.make({}))),\n );\n\n const material = yield* bytes(jwk.k);\n\n if (\n (jwk.alg !== undefined && jwk.alg !== algorithm) ||\n material.length < 32 ||\n (algorithm === \"dir\" && material.length !== 32)\n ) {\n material.fill(0);\n\n return yield* InvalidKey.make({});\n }\n\n return Object.freeze({\n _tag: \"SecretKey\",\n algorithm,\n jwk: Redacted.make(snapshot(jwk)),\n material: Redacted.make(material),\n }) satisfies SecretKey;\n});\n\nexport const exportPublic = Effect.fnUntraced(function* (key: PublicKey) {\n return yield* read(PublicJwk, key.jwk);\n});\n\nexport const exportPrivate = Effect.fnUntraced(function* (key: PrivateKey | SecretKey) {\n const value = yield* reveal<PrivateJwk | SecretJwk>(key.jwk).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n );\n\n return Redacted.make(yield* read(Schema.Union([PrivateJwk, SecretJwk]), value));\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@yielded/jose","version":"0.1.0-beta.28","dependencies":{"@yielded/crypto":"0.1.0-beta.28"},"devDependencies":{"@effect/platform-node":"4.0.0","@effect/vitest":"4.0.0","@types/node":"26.1.2","effect":"4.0.0","jose":"6.2.12","typescript":"7.0.2","vite-plus":"0.3.3"},"peerDependencies":{"effect":"^4.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./Errors":{"types":"./dist/Errors.d.mts","default":"./dist/Errors.mjs"},"./Jwk":{"types":"./dist/Jwk.d.mts","default":"./dist/Jwk.mjs"},"./Jwks":{"types":"./dist/Jwks.d.mts","default":"./dist/Jwks.mjs"},"./Jws":{"types":"./dist/Jws.d.mts","default":"./dist/Jws.mjs"},"./Jwt":{"types":"./dist/Jwt.d.mts","default":"./dist/Jwt.mjs"},"./Jwe":{"types":"./dist/Jwe.d.mts","default":"./dist/Jwe.mjs"}},"description":"Schema-typed Effect JOSE with explicit keys, cryptography, and remote JWKS trust.","homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/jose"},"files":["dist","src","THIRD_PARTY_NOTICES.md"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test"}}
1
+ {"name":"@yielded/jose","version":"0.1.0-beta.30","dependencies":{"@yielded/crypto":"0.1.0-beta.30"},"devDependencies":{"@effect/platform-node":"4.0.0","@effect/vitest":"4.0.0","@types/node":"26.1.2","effect":"4.0.0","jose":"6.2.12","typescript":"7.0.2","vite-plus":"0.3.3"},"peerDependencies":{"effect":"^4.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./Errors":{"types":"./dist/Errors.d.mts","default":"./dist/Errors.mjs"},"./Jwk":{"types":"./dist/Jwk.d.mts","default":"./dist/Jwk.mjs"},"./Jwks":{"types":"./dist/Jwks.d.mts","default":"./dist/Jwks.mjs"},"./Jws":{"types":"./dist/Jws.d.mts","default":"./dist/Jws.mjs"},"./Jwt":{"types":"./dist/Jwt.d.mts","default":"./dist/Jwt.mjs"},"./Jwe":{"types":"./dist/Jwe.d.mts","default":"./dist/Jwe.mjs"}},"description":"Schema-typed Effect JOSE with explicit keys, cryptography, and remote JWKS trust.","homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/jose"},"files":["dist","src","THIRD_PARTY_NOTICES.md"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test"}}
package/src/Jwk.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as Signature from "@yielded/crypto/Signature";
2
2
  import { Effect, Redacted, Schema } from "effect";
3
+ import { Base64Url } from "effect/encoding";
3
4
 
4
5
  import { InvalidKey } from "./Errors";
5
6
  import { algorithms } from "./internal/algorithms";
@@ -80,6 +81,24 @@ export const SecretJwk = Schema.Struct({
80
81
 
81
82
  export type SecretJwk = typeof SecretJwk.Type;
82
83
 
84
+ export const GenerateKeyPairInput = Schema.Union([
85
+ Schema.Struct({
86
+ algorithm: Schema.Literals(["RS256", "PS256"]),
87
+ modulusLength: Schema.optionalKey(Signature.RsaModulusLength),
88
+ kid: metadata.kid,
89
+ }),
90
+ Schema.Struct({ algorithm: Schema.Literals(["ES256", "EdDSA"]), kid: metadata.kid }),
91
+ ]);
92
+
93
+ export type GenerateKeyPairInput = typeof GenerateKeyPairInput.Type;
94
+
95
+ export const GeneratedKeyPair = Schema.Struct({
96
+ publicKey: PublicJwk,
97
+ privateKey: Schema.Redacted(PrivateJwk, { disallowJsonEncode: true }),
98
+ });
99
+
100
+ export type GeneratedKeyPair = typeof GeneratedKeyPair.Type;
101
+
83
102
  /** Validated, algorithm-bound key snapshots. Private material remains Redacted. */
84
103
  export interface PublicKey {
85
104
  readonly _tag: "PublicKey";
@@ -105,6 +124,90 @@ export interface SecretKey {
105
124
  export type SigningKey = PrivateKey | SecretKey;
106
125
  export type VerificationKey = PublicKey | SecretKey;
107
126
 
127
+ /** Generate typed signing JWKs through the selected crypto backend. */
128
+ export const generateKeyPair = Effect.fnUntraced(function* (input: GenerateKeyPairInput) {
129
+ const value = yield* Schema.decodeEffect(GenerateKeyPairInput)(input).pipe(
130
+ Effect.mapError(() => InvalidKey.make({})),
131
+ );
132
+
133
+ const signatures = yield* Signature.Signature;
134
+
135
+ return yield* Effect.acquireUseRelease(
136
+ signatures.generateKeyPair({
137
+ algorithm: algorithms[value.algorithm],
138
+ ...("modulusLength" in value ? { modulusLength: value.modulusLength } : {}),
139
+ }),
140
+ (pair) =>
141
+ Effect.sync((): GeneratedKeyPair => {
142
+ const parameters = Redacted.value(pair.privateKey);
143
+
144
+ const meta = {
145
+ alg: value.algorithm,
146
+ use: "sig" as const,
147
+ ...(value.kid === undefined ? {} : { kid: value.kid }),
148
+ };
149
+
150
+ switch (parameters.algorithm) {
151
+ case "RSASSA-PKCS1-v1_5-SHA256":
152
+ case "RSA-PSS-SHA256": {
153
+ const publicKey = {
154
+ ...meta,
155
+ kty: "RSA" as const,
156
+ n: Base64Url.encode(parameters.n),
157
+ e: Base64Url.encode(parameters.e),
158
+ };
159
+
160
+ return {
161
+ publicKey,
162
+ privateKey: Redacted.make({
163
+ ...publicKey,
164
+ d: Base64Url.encode(parameters.d),
165
+ p: Base64Url.encode(parameters.p),
166
+ q: Base64Url.encode(parameters.q),
167
+ dp: Base64Url.encode(parameters.dp),
168
+ dq: Base64Url.encode(parameters.dq),
169
+ qi: Base64Url.encode(parameters.qi),
170
+ }),
171
+ };
172
+ }
173
+ case "ECDSA-P256-SHA256": {
174
+ const publicKey = {
175
+ ...meta,
176
+ kty: "EC" as const,
177
+ crv: "P-256" as const,
178
+ x: Base64Url.encode(parameters.x),
179
+ y: Base64Url.encode(parameters.y),
180
+ };
181
+
182
+ return {
183
+ publicKey,
184
+ privateKey: Redacted.make({ ...publicKey, d: Base64Url.encode(parameters.d) }),
185
+ };
186
+ }
187
+ case "Ed25519": {
188
+ const publicKey = {
189
+ ...meta,
190
+ kty: "OKP" as const,
191
+ crv: "Ed25519" as const,
192
+ x: Base64Url.encode(parameters.x),
193
+ };
194
+
195
+ return {
196
+ publicKey,
197
+ privateKey: Redacted.make({ ...publicKey, d: Base64Url.encode(parameters.d) }),
198
+ };
199
+ }
200
+ }
201
+ }),
202
+ (pair) =>
203
+ Effect.sync(() => {
204
+ for (const part of Object.values(Redacted.value(pair.privateKey))) {
205
+ if (typeof part !== "string") part.fill(0);
206
+ }
207
+ }),
208
+ );
209
+ });
210
+
108
211
  const read = <S extends Schema.Constraint>(schema: S, input: unknown) =>
109
212
  Effect.try({
110
213
  try: () => KeyInput.jwk(input),