@authup/server-kit 1.0.0-beta.23 → 1.0.0-beta.25

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.
Files changed (101) hide show
  1. package/LICENSE +1 -1
  2. package/dist/crypto/index.d.ts +3 -1
  3. package/dist/crypto/index.d.ts.map +1 -1
  4. package/dist/crypto/json-web-token/extract.d.ts +7 -2
  5. package/dist/crypto/json-web-token/extract.d.ts.map +1 -1
  6. package/dist/crypto/json-web-token/sign/module.d.ts +1 -1
  7. package/dist/crypto/json-web-token/sign/module.d.ts.map +1 -1
  8. package/dist/crypto/json-web-token/sign/types.d.ts +10 -5
  9. package/dist/crypto/json-web-token/sign/types.d.ts.map +1 -1
  10. package/dist/crypto/json-web-token/type.d.ts +1 -1
  11. package/dist/crypto/json-web-token/type.d.ts.map +1 -1
  12. package/dist/crypto/json-web-token/utils.d.ts +2 -2
  13. package/dist/crypto/json-web-token/utils.d.ts.map +1 -1
  14. package/dist/crypto/json-web-token/verify/module.d.ts +2 -2
  15. package/dist/crypto/json-web-token/verify/module.d.ts.map +1 -1
  16. package/dist/crypto/json-web-token/verify/types.d.ts +10 -5
  17. package/dist/crypto/json-web-token/verify/types.d.ts.map +1 -1
  18. package/dist/crypto/key/container.d.ts +14 -0
  19. package/dist/crypto/key/container.d.ts.map +1 -0
  20. package/dist/crypto/key/index.d.ts +3 -0
  21. package/dist/crypto/key/index.d.ts.map +1 -0
  22. package/dist/crypto/key/key-usages.d.ts +2 -0
  23. package/dist/crypto/key/key-usages.d.ts.map +1 -0
  24. package/dist/crypto/key/types.d.ts +14 -0
  25. package/dist/crypto/key/types.d.ts.map +1 -0
  26. package/dist/crypto/key-asymmetric/check.d.ts +3 -0
  27. package/dist/crypto/key-asymmetric/check.d.ts.map +1 -0
  28. package/dist/crypto/key-asymmetric/constants.d.ts +8 -0
  29. package/dist/crypto/key-asymmetric/constants.d.ts.map +1 -0
  30. package/dist/crypto/key-asymmetric/create.d.ts +3 -0
  31. package/dist/crypto/key-asymmetric/create.d.ts.map +1 -0
  32. package/dist/crypto/key-asymmetric/helpers/index.d.ts +2 -0
  33. package/dist/crypto/key-asymmetric/helpers/index.d.ts.map +1 -0
  34. package/dist/crypto/key-asymmetric/helpers/wrap.d.ts +5 -0
  35. package/dist/crypto/key-asymmetric/helpers/wrap.d.ts.map +1 -0
  36. package/dist/crypto/key-asymmetric/index.d.ts +8 -0
  37. package/dist/crypto/key-asymmetric/index.d.ts.map +1 -0
  38. package/dist/crypto/key-asymmetric/key-usages.d.ts +5 -0
  39. package/dist/crypto/key-asymmetric/key-usages.d.ts.map +1 -0
  40. package/dist/crypto/key-asymmetric/normalize.d.ts +4 -0
  41. package/dist/crypto/key-asymmetric/normalize.d.ts.map +1 -0
  42. package/dist/crypto/key-asymmetric/types.d.ts +30 -0
  43. package/dist/crypto/key-asymmetric/types.d.ts.map +1 -0
  44. package/dist/crypto/key-symmetric/check.d.ts +3 -0
  45. package/dist/crypto/key-symmetric/check.d.ts.map +1 -0
  46. package/dist/crypto/key-symmetric/constants.d.ts +7 -0
  47. package/dist/crypto/key-symmetric/constants.d.ts.map +1 -0
  48. package/dist/crypto/key-symmetric/create.d.ts +3 -0
  49. package/dist/crypto/key-symmetric/create.d.ts.map +1 -0
  50. package/dist/crypto/key-symmetric/index.d.ts +6 -0
  51. package/dist/crypto/key-symmetric/index.d.ts.map +1 -0
  52. package/dist/crypto/key-symmetric/key-usages.d.ts +2 -0
  53. package/dist/crypto/key-symmetric/key-usages.d.ts.map +1 -0
  54. package/dist/crypto/key-symmetric/normalize.d.ts +4 -0
  55. package/dist/crypto/key-symmetric/normalize.d.ts.map +1 -0
  56. package/dist/crypto/key-symmetric/types.d.ts +27 -0
  57. package/dist/crypto/key-symmetric/types.d.ts.map +1 -0
  58. package/dist/domain-event/module.d.ts +1 -1
  59. package/dist/domain-event/module.d.ts.map +1 -1
  60. package/dist/domain-event/type.d.ts +1 -1
  61. package/dist/domain-event/type.d.ts.map +1 -1
  62. package/dist/index.cjs +335 -296
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.mjs +304 -247
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/services/cache/adapters/memory.d.ts +1 -0
  67. package/dist/services/cache/adapters/memory.d.ts.map +1 -1
  68. package/dist/services/cache/adapters/redis.d.ts +1 -0
  69. package/dist/services/cache/adapters/redis.d.ts.map +1 -1
  70. package/dist/services/cache/adapters/types.d.ts +1 -0
  71. package/dist/services/cache/adapters/types.d.ts.map +1 -1
  72. package/dist/services/logger/module.d.ts.map +1 -1
  73. package/package.json +15 -8
  74. package/dist/crypto/key-pair/constants.d.ts +0 -5
  75. package/dist/crypto/key-pair/constants.d.ts.map +0 -1
  76. package/dist/crypto/key-pair/create.d.ts +0 -3
  77. package/dist/crypto/key-pair/create.d.ts.map +0 -1
  78. package/dist/crypto/key-pair/delete.d.ts +0 -3
  79. package/dist/crypto/key-pair/delete.d.ts.map +0 -1
  80. package/dist/crypto/key-pair/helpers/check.d.ts +0 -4
  81. package/dist/crypto/key-pair/helpers/check.d.ts.map +0 -1
  82. package/dist/crypto/key-pair/helpers/file-name.d.ts +0 -4
  83. package/dist/crypto/key-pair/helpers/file-name.d.ts.map +0 -1
  84. package/dist/crypto/key-pair/helpers/index.d.ts +0 -6
  85. package/dist/crypto/key-pair/helpers/index.d.ts.map +0 -1
  86. package/dist/crypto/key-pair/helpers/options.d.ts +0 -3
  87. package/dist/crypto/key-pair/helpers/options.d.ts.map +0 -1
  88. package/dist/crypto/key-pair/helpers/private-key.d.ts +0 -3
  89. package/dist/crypto/key-pair/helpers/private-key.d.ts.map +0 -1
  90. package/dist/crypto/key-pair/helpers/wrap.d.ts +0 -5
  91. package/dist/crypto/key-pair/helpers/wrap.d.ts.map +0 -1
  92. package/dist/crypto/key-pair/index.d.ts +0 -9
  93. package/dist/crypto/key-pair/index.d.ts.map +0 -1
  94. package/dist/crypto/key-pair/load.d.ts +0 -3
  95. package/dist/crypto/key-pair/load.d.ts.map +0 -1
  96. package/dist/crypto/key-pair/module.d.ts +0 -3
  97. package/dist/crypto/key-pair/module.d.ts.map +0 -1
  98. package/dist/crypto/key-pair/save.d.ts +0 -3
  99. package/dist/crypto/key-pair/save.d.ts.map +0 -1
  100. package/dist/crypto/key-pair/type.d.ts +0 -64
  101. package/dist/crypto/key-pair/type.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,18 +1,19 @@
1
1
  import { compare as compare$1, hash as hash$1 } from '@node-rs/bcrypt';
2
- import { createPrivateKey, generateKeyPair, createPublicKey } from 'node:crypto';
3
- import { isObject, TokenError, JWTAlgorithm, JWKType, buildEventFullName } from '@authup/kit';
4
- import path from 'node:path';
5
- import fs from 'node:fs';
2
+ import { subtle } from 'uncrypto';
3
+ import { arrayBufferToBase64, base64ToArrayBuffer, isObject as isObject$1 } from '@authup/kit';
4
+ import { JWTError, JWTAlgorithm, JWKType, OAuth2Error } from '@authup/specs';
6
5
  import { Algorithm, sign, verify } from '@node-rs/jsonwebtoken';
7
- import { isObject as isObject$1 } from 'smob';
6
+ import { isObject } from 'smob';
8
7
  import { JsonAdapter, buildKeyPath } from 'redis-extension';
9
8
  export { Client as RedisClient, ClientOptions as RedisClientOptions, JsonAdapter as RedisJsonAdapter, Watcher as RedisWatcher, buildKeyPath as buildRedisKeyPath, createClient as createRedisClient, escapeKey as escapeRedisKey, parseKeyPath as parseRedisKeyPath } from 'redis-extension';
10
9
  import { singa } from 'singa';
11
10
  import TTLCache from '@isaacs/ttlcache';
12
- import * as process$1 from 'node:process';
11
+ import path from 'node:path';
12
+ import process from 'node:process';
13
13
  import { transports, createLogger as createLogger$1, format } from 'winston';
14
14
  export { Logger } from 'winston';
15
15
  export { VaultClient, createClient as createVaultClient } from '@hapic/vault';
16
+ import { buildEventFullName } from '@authup/core-realtime-kit';
16
17
  import { Emitter } from '@socket.io/redis-emitter';
17
18
 
18
19
  async function compare(value, hashedValue) {
@@ -28,103 +29,124 @@ async function hash(str, rounds = 10) {
28
29
  * Author Peter Placzek (tada5hi)
29
30
  * For the full copyright and license information,
30
31
  * view the LICENSE file that was distributed with this source code.
31
- */ var KeyPairKind = /*#__PURE__*/ function(KeyPairKind) {
32
- KeyPairKind["PRIVATE"] = "private";
33
- KeyPairKind["PUBLIC"] = "public";
34
- return KeyPairKind;
32
+ */ var CryptoAsymmetricAlgorithm = /*#__PURE__*/ function(CryptoAsymmetricAlgorithm) {
33
+ CryptoAsymmetricAlgorithm["RSA_PSS"] = "RSA-PSS";
34
+ CryptoAsymmetricAlgorithm["RSASSA_PKCS1_V1_5"] = "RSASSA-PKCS1-v1_5";
35
+ CryptoAsymmetricAlgorithm["RSA_OAEP"] = "RSA-OAEP";
36
+ CryptoAsymmetricAlgorithm["ECDSA"] = "ECDSA";
37
+ CryptoAsymmetricAlgorithm["ECDH"] = "ECDH";
38
+ return CryptoAsymmetricAlgorithm;
35
39
  }({});
36
40
 
37
- function isKeyPair(data) {
38
- return isObject(data) && typeof data.privateKey !== 'undefined' && typeof data.publicKey !== 'undefined';
39
- }
40
- function isKeyPairWithPublicKey(data) {
41
- return isObject(data) && typeof data.publicKey !== 'undefined';
41
+ function isAsymmetricAlgorithm(input) {
42
+ return Object.values(CryptoAsymmetricAlgorithm).indexOf(input) !== -1;
42
43
  }
43
44
 
44
- function extendKeyPairOptions(options) {
45
- var _options;
46
- options = options ?? {};
47
- options.directory = options.directory || process.cwd();
48
- options.directory = path.isAbsolute(options.directory) ? options.directory : path.resolve(process.cwd(), options.directory);
49
- (_options = options).type ?? (_options.type = 'rsa');
50
- if (options.type === 'rsa' || options.type === 'rsa-pss' || options.type === 'dsa') {
51
- options.modulusLength = 2048;
52
- }
53
- if (!options.privateKeyEncoding) {
54
- options.privateKeyEncoding = {
55
- type: 'pkcs8',
56
- format: 'pem'
57
- };
45
+ /**
46
+ * @see https://nodejs.org/api/webcrypto.html#cryptokeyusages
47
+ */ function getKeyUsagesForAsymmetricAlgorithm(name, format) {
48
+ if (name === CryptoAsymmetricAlgorithm.RSA_PSS || name === CryptoAsymmetricAlgorithm.ECDSA || name === CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5) {
49
+ if (format === 'spki') {
50
+ return [
51
+ 'verify'
52
+ ];
53
+ }
54
+ if (format === 'pkcs8') {
55
+ return [
56
+ 'sign'
57
+ ];
58
+ }
59
+ return [
60
+ 'sign',
61
+ 'verify'
62
+ ];
58
63
  }
59
- if (!options.publicKeyEncoding) {
60
- options.publicKeyEncoding = {
61
- type: 'spki',
62
- format: 'pem'
63
- };
64
+ if (name === CryptoAsymmetricAlgorithm.ECDH) {
65
+ if (format === 'spki') {
66
+ return [];
67
+ }
68
+ return [
69
+ 'deriveKey',
70
+ 'deriveBits'
71
+ ];
64
72
  }
65
- if (options.privateKeyEncoding.passphrase && !options.privateKeyEncoding.cipher) {
66
- options.privateKeyEncoding.cipher = 'aes-256-cbc';
73
+ if (name === CryptoAsymmetricAlgorithm.RSA_OAEP) {
74
+ if (format === 'spki') {
75
+ return [
76
+ 'encrypt'
77
+ ];
78
+ }
79
+ if (format === 'pkcs8') {
80
+ return [
81
+ 'decrypt'
82
+ ];
83
+ }
84
+ return [
85
+ 'encrypt',
86
+ 'decrypt'
87
+ ];
67
88
  }
68
- return options;
89
+ throw new SyntaxError(`Key usages can not be determined for asymmetric algorithm: ${name}`);
69
90
  }
70
91
 
71
- function buildKeyFileName(type, context) {
72
- const options = extendKeyPairOptions(context);
73
- const parts = [];
74
- switch(type){
75
- case KeyPairKind.PRIVATE:
92
+ function normalizeAsymmetricKeyPairCreateOptions(options) {
93
+ let optionsNormalized;
94
+ switch(options.name){
95
+ case CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5:
96
+ case CryptoAsymmetricAlgorithm.RSA_PSS:
97
+ case CryptoAsymmetricAlgorithm.RSA_OAEP:
76
98
  {
77
- if (options.privateName) {
78
- parts.push(options.privateName);
79
- } else {
80
- parts.push(type);
81
- }
82
- if (options.privateExtension) {
83
- if (options.privateExtension.startsWith('.')) {
84
- options.privateExtension = options.privateExtension.slice(1);
85
- }
86
- parts.push(options.privateExtension);
87
- } else {
88
- parts.push('pem');
89
- }
99
+ optionsNormalized = {
100
+ modulusLength: 2048,
101
+ publicExponent: new Uint8Array([
102
+ 0x01,
103
+ 0x00,
104
+ 0x01
105
+ ]),
106
+ hash: 'SHA-256',
107
+ ...options
108
+ };
90
109
  break;
91
110
  }
92
- case KeyPairKind.PUBLIC:
111
+ case CryptoAsymmetricAlgorithm.ECDSA:
112
+ case CryptoAsymmetricAlgorithm.ECDH:
93
113
  {
94
- if (options.publicName) {
95
- parts.push(options.publicName);
96
- } else {
97
- parts.push(type);
98
- }
99
- if (options.publicExtension) {
100
- if (options.publicExtension.startsWith('.')) {
101
- options.publicExtension = options.publicExtension.slice(1);
102
- }
103
- parts.push(options.publicExtension);
104
- } else {
105
- parts.push('pem');
106
- }
114
+ optionsNormalized = {
115
+ namedCurve: 'P-256',
116
+ ...options
117
+ };
118
+ }
119
+ }
120
+ return optionsNormalized;
121
+ }
122
+ function normalizeAsymmetricKeyImportOptions(options) {
123
+ let optionsNormalized;
124
+ switch(options.name){
125
+ case CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5:
126
+ case CryptoAsymmetricAlgorithm.RSA_PSS:
127
+ case CryptoAsymmetricAlgorithm.RSA_OAEP:
128
+ {
129
+ optionsNormalized = {
130
+ hash: 'SHA-256',
131
+ ...options
132
+ };
107
133
  break;
108
134
  }
135
+ case CryptoAsymmetricAlgorithm.ECDSA:
136
+ case CryptoAsymmetricAlgorithm.ECDH:
137
+ {
138
+ optionsNormalized = {
139
+ namedCurve: 'P-256',
140
+ ...options
141
+ };
142
+ }
109
143
  }
110
- return parts.join('.');
144
+ return optionsNormalized;
111
145
  }
112
146
 
113
- function decryptRSAPrivateKey(context, key) {
114
- const privateKey = createPrivateKey({
115
- type: context.privateKeyEncoding.type,
116
- format: context.privateKeyEncoding.format,
117
- key,
118
- passphrase: context.privateKeyEncoding.passphrase || context.passphrase
119
- });
120
- let content = privateKey.export({
121
- type: context.privateKeyEncoding.type,
122
- format: context.privateKeyEncoding.format
123
- });
124
- if (typeof content !== 'string') {
125
- content = Buffer.from(content).toString('utf-8');
126
- }
127
- return content;
147
+ async function createAsymmetricKeyPair(options) {
148
+ const optionsNormalized = normalizeAsymmetricKeyPairCreateOptions(options);
149
+ return subtle.generateKey(optionsNormalized, true, getKeyUsagesForAsymmetricAlgorithm(optionsNormalized.name));
128
150
  }
129
151
 
130
152
  /*
@@ -132,172 +154,169 @@ function decryptRSAPrivateKey(context, key) {
132
154
  * Author Peter Placzek (tada5hi)
133
155
  * For the full copyright and license information,
134
156
  * view the LICENSE file that was distributed with this source code.
135
- */ function wrapPem(type, input) {
136
- if (typeof input !== 'string') {
137
- input = Buffer.from(input).toString('base64');
138
- }
157
+ */ function enc(type, input) {
139
158
  return `-----BEGIN ${type}-----\n${input}\n-----END ${type}-----`;
140
159
  }
141
- function wrapPrivateKeyPem(input) {
142
- return wrapPem('PRIVATE KEY', input);
160
+ function encodePKCS8ToPEM(base64) {
161
+ return enc('PRIVATE KEY', base64);
143
162
  }
144
- function wrapPublicKeyPem(input) {
145
- return wrapPem('PUBLIC KEY', input);
163
+ function encodeSPKIToPem(input) {
164
+ return enc('PUBLIC KEY', input);
146
165
  }
147
166
  // ------------------------------------------------------------
148
- function unwrapPem(type, input) {
149
- if (typeof input !== 'string') {
150
- input = Buffer.from(input).toString('base64');
151
- }
167
+ function dec(type, input) {
152
168
  input = input.replace(`-----BEGIN ${type}-----\n`, '');
153
169
  input = input.replace(`\n-----END ${type}-----\n`, '');
154
170
  input = input.replace(`-----END ${type}-----\n`, '');
155
171
  input = input.replace(`\n-----END ${type}-----`, '');
156
172
  return input;
157
173
  }
158
- function unwrapPrivateKeyPem(input) {
159
- return unwrapPem('PRIVATE KEY', input);
174
+ function decodePemToPKCS8(input) {
175
+ return dec('PRIVATE KEY', input);
160
176
  }
161
- function unwrapPublicKeyPem(input) {
162
- return unwrapPem('PUBLIC KEY', input);
177
+ function decodePemToSpki(input) {
178
+ return dec('PUBLIC KEY', input);
163
179
  }
164
180
 
165
- async function saveKeyPair(keyPair, context) {
166
- context = extendKeyPairOptions(context);
167
- await fs.promises.mkdir(context.directory, {
168
- recursive: true
169
- });
170
- await Promise.all([
171
- {
172
- path: path.resolve(context.directory, buildKeyFileName(KeyPairKind.PRIVATE, context)),
173
- content: keyPair.privateKey
174
- },
175
- {
176
- path: path.resolve(context.directory, buildKeyFileName(KeyPairKind.PUBLIC, context)),
177
- content: keyPair.publicKey
178
- }
179
- ].map((file)=>fs.promises.writeFile(file.path, file.content)));
180
- return keyPair;
181
- }
182
-
183
- async function createKeyPair(context) {
184
- const options = extendKeyPairOptions(context);
185
- const keyPair = await new Promise((resolve, reject)=>{
186
- const callback = (err, publicKey, privateKey)=>{
187
- if (err) reject(err);
188
- resolve({
189
- privateKey,
190
- publicKey
191
- });
181
+ /*
182
+ * Copyright (c) 2024.
183
+ * Author Peter Placzek (tada5hi)
184
+ * For the full copyright and license information,
185
+ * view the LICENSE file that was distributed with this source code.
186
+ */ var SymmetricAlgorithm = /*#__PURE__*/ function(SymmetricAlgorithm) {
187
+ SymmetricAlgorithm["HMAC"] = "HMAC";
188
+ SymmetricAlgorithm["AES_CTR"] = "AES-CTR";
189
+ SymmetricAlgorithm["AES_CBC"] = "AES-CBC";
190
+ SymmetricAlgorithm["AES_GCM"] = "AES-GCM";
191
+ return SymmetricAlgorithm;
192
+ }({});
193
+
194
+ function normalizeSymmetricKeyCreateOptions(input) {
195
+ if (input.name === SymmetricAlgorithm.HMAC) {
196
+ return {
197
+ hash: 'SHA-256',
198
+ ...input
192
199
  };
193
- switch(options.type){
194
- case 'dsa':
195
- generateKeyPair(options.type, options, callback);
196
- break;
197
- case 'ec':
198
- generateKeyPair(options.type, options, callback);
199
- break;
200
- case 'rsa':
201
- generateKeyPair(options.type, options, callback);
202
- break;
203
- case 'rsa-pss':
204
- generateKeyPair(options.type, options, callback);
205
- break;
206
- }
207
- });
208
- if (options.save) {
209
- await saveKeyPair(keyPair, options);
210
200
  }
211
- if (options.passphrase || options.privateKeyEncoding.passphrase) {
212
- keyPair.privateKey = decryptRSAPrivateKey(options, keyPair.privateKey);
201
+ return {
202
+ length: 256,
203
+ name: input.name
204
+ };
205
+ }
206
+ function normalizeSymmetricKeyImportOptions(input) {
207
+ if (input.name === SymmetricAlgorithm.HMAC) {
208
+ return {
209
+ hash: 'SHA-256',
210
+ ...input
211
+ };
212
+ }
213
+ return input;
214
+ }
215
+
216
+ function isSymmetricAlgorithm(input) {
217
+ return Object.values(SymmetricAlgorithm).indexOf(input) !== -1;
218
+ }
219
+
220
+ function getKeyUsagesForSymmetricAlgorithm(name) {
221
+ /**
222
+ * @see https://nodejs.org/api/webcrypto.html#cryptokeyusages
223
+ */ if (name === SymmetricAlgorithm.HMAC) {
224
+ return [
225
+ 'sign',
226
+ 'verify'
227
+ ];
228
+ }
229
+ if (name === SymmetricAlgorithm.AES_CBC || name === SymmetricAlgorithm.AES_GCM || name === SymmetricAlgorithm.AES_CTR) {
230
+ return [
231
+ 'encrypt',
232
+ 'decrypt'
233
+ ];
213
234
  }
214
- return keyPair;
235
+ throw new SyntaxError(`Key usages can not be determined for symmetric algorithm: ${name}`);
215
236
  }
216
237
 
217
- async function deleteKeyPair(context) {
218
- const options = extendKeyPairOptions(context);
219
- const privateKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PRIVATE, options));
220
- const publicKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PUBLIC, options));
221
- try {
222
- await Promise.all([
223
- privateKeyPath,
224
- publicKeyPath
225
- ].map((filePath)=>fs.promises.stat(filePath)));
226
- } catch (e) {
227
- return;
238
+ async function createSymmetricKey(input) {
239
+ const optionsNormalized = normalizeSymmetricKeyCreateOptions(input);
240
+ return subtle.generateKey(optionsNormalized, true, getKeyUsagesForSymmetricAlgorithm(optionsNormalized.name));
241
+ }
242
+
243
+ function getKeyUsagesForAlgorithm(name, format) {
244
+ if (isAsymmetricAlgorithm(name)) {
245
+ return getKeyUsagesForAsymmetricAlgorithm(name, format);
246
+ }
247
+ if (isSymmetricAlgorithm(name)) {
248
+ return getKeyUsagesForSymmetricAlgorithm(name);
228
249
  }
229
- await Promise.all([
230
- privateKeyPath,
231
- publicKeyPath
232
- ].map((filePath)=>fs.promises.rm(filePath)));
250
+ throw new SyntaxError(`Key usages can not be determined for algorithm: ${name}`);
233
251
  }
234
252
 
235
- async function loadKeyPair(context) {
236
- const options = extendKeyPairOptions(context);
237
- const privateKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PRIVATE, options));
238
- try {
239
- await fs.promises.stat(privateKeyPath);
240
- } catch (e) {
241
- return undefined;
253
+ class CryptoKeyContainer {
254
+ // ----------------------------------------------
255
+ async toArrayBuffer() {
256
+ if (this.key.type === 'private') {
257
+ return subtle.exportKey('pkcs8', this.key);
258
+ }
259
+ if (this.key.type === 'public') {
260
+ return subtle.exportKey('spki', this.key);
261
+ }
262
+ return subtle.exportKey('raw', this.key);
242
263
  }
243
- const privateKeyBuffer = await fs.promises.readFile(privateKeyPath);
244
- let privateKey = privateKeyBuffer.toString();
245
- if (options.passphrase || options.privateKeyEncoding.passphrase) {
246
- privateKey = decryptRSAPrivateKey(options, privateKey);
264
+ async toUint8Array() {
265
+ const arrayBuffer = await this.toArrayBuffer();
266
+ return new Uint8Array(arrayBuffer);
247
267
  }
248
- const publicKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PUBLIC, options));
249
- let publicKey;
250
- try {
251
- await fs.promises.stat(publicKeyPath);
252
- const publicKeyBuffer = await fs.promises.readFile(publicKeyPath);
253
- publicKey = publicKeyBuffer.toString();
254
- } catch (e) {
255
- const publicKeyObject = createPublicKey({
256
- key: privateKey,
257
- format: options.privateKeyEncoding.format,
258
- type: options.publicKeyEncoding.type
259
- });
260
- const stringOrBuffer = publicKeyObject.export({
261
- format: options.publicKeyEncoding.format,
262
- type: options.publicKeyEncoding.type
263
- });
264
- if (typeof stringOrBuffer !== 'string') {
265
- publicKey = stringOrBuffer.toString();
266
- } else {
267
- publicKey = stringOrBuffer;
268
+ async toBase64() {
269
+ const arrayBuffer = await this.toArrayBuffer();
270
+ return arrayBufferToBase64(arrayBuffer);
271
+ }
272
+ async toPem() {
273
+ const base64 = await this.toBase64();
274
+ if (this.key.type === 'public') {
275
+ return encodeSPKIToPem(base64);
268
276
  }
269
- if (options.save) {
270
- await saveKeyPair({
271
- privateKey,
272
- publicKey
273
- }, options);
277
+ if (this.key.type === 'private') {
278
+ return encodePKCS8ToPEM(base64);
274
279
  }
280
+ throw new Error('A symmetric key can not be encoded as PEM');
275
281
  }
276
- return {
277
- privateKey,
278
- publicKey
279
- };
280
- }
281
-
282
- const keyPairCache = {};
283
- async function useKeyPair(value) {
284
- let options;
285
- if (typeof value === 'string') {
286
- options = extendKeyPairOptions({
287
- privateName: value
282
+ async toJWK() {
283
+ return subtle.exportKey('jwk', this.key);
284
+ }
285
+ // ----------------------------------------------
286
+ static async fromPem(ctx) {
287
+ if (ctx.format === 'pkcs8') {
288
+ return CryptoKeyContainer.fromBase64({
289
+ ...ctx,
290
+ key: decodePemToPKCS8(ctx.key)
291
+ });
292
+ }
293
+ return CryptoKeyContainer.fromBase64({
294
+ ...ctx,
295
+ key: decodePemToSpki(ctx.key)
296
+ });
297
+ }
298
+ static async fromBase64(ctx) {
299
+ const arrayBuffer = base64ToArrayBuffer(ctx.key);
300
+ return CryptoKeyContainer.fromArrayBuffer({
301
+ ...ctx,
302
+ key: arrayBuffer
288
303
  });
289
- } else {
290
- options = extendKeyPairOptions(value || {});
291
304
  }
292
- if (Object.prototype.hasOwnProperty.call(keyPairCache, options.privateName)) {
293
- return keyPairCache[options.privateName];
305
+ static async fromArrayBuffer(ctx) {
306
+ let normalizedOptions;
307
+ if (ctx.format === 'spki' || ctx.format === 'pkcs8') {
308
+ normalizedOptions = normalizeAsymmetricKeyImportOptions(ctx.options);
309
+ } else if (ctx.format === 'raw') {
310
+ normalizedOptions = normalizeSymmetricKeyImportOptions(ctx.options);
311
+ } else {
312
+ throw new SyntaxError(`Format ${ctx.format} is not supported.`);
313
+ }
314
+ const cryptoKey = await subtle.importKey(ctx.format, ctx.key, normalizedOptions, true, getKeyUsagesForAlgorithm(normalizedOptions.name, ctx.format));
315
+ return new CryptoKeyContainer(cryptoKey);
294
316
  }
295
- let keyPair = await loadKeyPair(options);
296
- if (typeof keyPair === 'undefined') {
297
- keyPair = await createKeyPair(options);
317
+ constructor(cryptoKey){
318
+ this.key = cryptoKey;
298
319
  }
299
- keyPairCache[options.privateName] = keyPair;
300
- return keyPair;
301
320
  }
302
321
 
303
322
  /**
@@ -305,11 +324,11 @@ async function useKeyPair(value) {
305
324
  *
306
325
  * @param token
307
326
  *
308
- * @throws TokenError
327
+ * @throws JWTError
309
328
  */ function extractTokenHeader(token) {
310
329
  const parts = token.split('.');
311
330
  if (parts.length !== 3) {
312
- throw TokenError.payloadInvalid('The token format is not valid.');
331
+ throw JWTError.invalid();
313
332
  }
314
333
  const [headerBase64] = parts;
315
334
  try {
@@ -328,42 +347,46 @@ async function useKeyPair(value) {
328
347
  'x5t#S256': header.x5TS256CertThumbprint,
329
348
  };
330
349
  */ } catch (e) {
331
- throw TokenError.headerInvalid('The token header could not be extracted.');
350
+ throw JWTError.headerInvalid('The token header could not be extracted.');
332
351
  }
333
352
  }
334
- function extractTokenPayload(token) {
353
+ /**
354
+ * @param token
355
+ *
356
+ * @throws JWTError
357
+ */ function extractTokenPayload(token) {
335
358
  const parts = token.split('.');
336
359
  if (parts.length !== 3) {
337
- throw TokenError.payloadInvalid('The token format is not valid.');
360
+ throw JWTError.invalid();
338
361
  }
339
362
  const [, payloadBase64] = parts;
340
363
  try {
341
364
  const payload = atob(payloadBase64);
342
365
  return JSON.parse(payload);
343
366
  } catch (e) {
344
- throw TokenError.payloadInvalid('The token payload could not be extracted.');
367
+ throw JWTError.payloadInvalid('The token payload could not be extracted.');
345
368
  }
346
369
  }
347
370
 
348
371
  function createErrorForJWTError(e) {
349
- if (isObject$1(e)) {
372
+ if (isObject(e)) {
350
373
  if (typeof e.name === 'string') {
351
374
  switch(e.name){
352
375
  case 'TokenExpiredError':
353
376
  {
354
- return TokenError.expired();
377
+ return JWTError.expired();
355
378
  }
356
379
  case 'NotBeforeError':
357
380
  {
358
381
  if (typeof e.date === 'string' || e.date instanceof Date) {
359
- return TokenError.notActiveBefore(e.date);
382
+ return JWTError.notActiveBefore(e.date);
360
383
  }
361
384
  break;
362
385
  }
363
386
  case 'JsonWebTokenError':
364
387
  {
365
388
  if (typeof e.message === 'string') {
366
- return TokenError.payloadInvalid(e.message);
389
+ return JWTError.payloadInvalid(e.message);
367
390
  }
368
391
  break;
369
392
  }
@@ -373,20 +396,20 @@ function createErrorForJWTError(e) {
373
396
  switch(e.message){
374
397
  case 'ExpiredSignature':
375
398
  {
376
- return TokenError.expired();
399
+ return JWTError.expired();
377
400
  }
378
401
  case 'ImmatureSignature':
379
402
  {
380
- return TokenError.notActiveBefore();
403
+ return JWTError.notActiveBefore();
381
404
  }
382
405
  case 'InvalidToken':
383
406
  case 'InvalidSignature':
384
407
  {
385
- return TokenError.payloadInvalid();
408
+ return JWTError.payloadInvalid();
386
409
  }
387
410
  }
388
411
  }
389
- return new TokenError({
412
+ return new JWTError({
390
413
  cause: e,
391
414
  logMessage: true,
392
415
  message: 'The JWT error could not be determined.'
@@ -454,14 +477,20 @@ async function signToken(claims, context) {
454
477
  case JWKType.RSA:
455
478
  case JWKType.EC:
456
479
  {
457
- const { privateKey } = isKeyPair(context.keyPair) ? context.keyPair : await useKeyPair(context.keyPair);
458
480
  let algorithm;
481
+ let key;
482
+ if (typeof context.key === 'string') {
483
+ key = encodePKCS8ToPEM(context.key);
484
+ } else {
485
+ const keyContainer = new CryptoKeyContainer(context.key);
486
+ key = await keyContainer.toPem();
487
+ }
459
488
  if (context.type === JWKType.RSA) {
460
489
  algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : Algorithm.RS256;
461
490
  } else {
462
491
  algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : Algorithm.ES256;
463
492
  }
464
- return sign(claims, privateKey, {
493
+ return sign(claims, key, {
465
494
  algorithm,
466
495
  keyId: context.keyId
467
496
  });
@@ -469,13 +498,20 @@ async function signToken(claims, context) {
469
498
  case JWKType.OCT:
470
499
  {
471
500
  const algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : Algorithm.HS256;
472
- return sign(claims, context.key, {
501
+ let key;
502
+ if (typeof context.key === 'string') {
503
+ key = context.key;
504
+ } else {
505
+ const keyContainer = new CryptoKeyContainer(context.key);
506
+ key = await keyContainer.toUint8Array();
507
+ }
508
+ return sign(claims, key, {
473
509
  algorithm,
474
510
  keyId: context.keyId
475
511
  });
476
512
  }
477
513
  }
478
- throw new TokenError();
514
+ throw new OAuth2Error();
479
515
  }
480
516
 
481
517
  /**
@@ -484,7 +520,7 @@ async function signToken(claims, context) {
484
520
  * @param token
485
521
  * @param context
486
522
  *
487
- * @throws TokenError
523
+ * @throws OAuth2Error
488
524
  */ async function verifyToken(token, context) {
489
525
  let promise;
490
526
  let output;
@@ -493,7 +529,6 @@ async function signToken(claims, context) {
493
529
  case JWKType.RSA:
494
530
  case JWKType.EC:
495
531
  {
496
- const { publicKey } = isKeyPairWithPublicKey(context.keyPair) ? context.keyPair : await useKeyPair(context.keyPair);
497
532
  let algorithms;
498
533
  if (context.type === JWKType.RSA) {
499
534
  algorithms = context.algorithms ? context.algorithms.map((algorithm)=>transformJWTAlgorithmToInternal(algorithm)) : [
@@ -510,7 +545,14 @@ async function signToken(claims, context) {
510
545
  Algorithm.ES384
511
546
  ];
512
547
  }
513
- promise = verify(token, publicKey, {
548
+ let key;
549
+ if (typeof context.key === 'string') {
550
+ key = encodeSPKIToPem(context.key);
551
+ } else {
552
+ const keyContainer = new CryptoKeyContainer(context.key);
553
+ key = await keyContainer.toPem();
554
+ }
555
+ promise = verify(token, key, {
514
556
  algorithms,
515
557
  validateNbf: true
516
558
  });
@@ -523,7 +565,14 @@ async function signToken(claims, context) {
523
565
  Algorithm.HS384,
524
566
  Algorithm.HS512
525
567
  ];
526
- promise = verify(token, context.key, {
568
+ let key;
569
+ if (typeof context.key === 'string') {
570
+ key = context.key;
571
+ } else {
572
+ const keyContainer = new CryptoKeyContainer(context.key);
573
+ key = await keyContainer.toUint8Array();
574
+ }
575
+ promise = verify(token, key, {
527
576
  algorithms,
528
577
  validateNbf: true
529
578
  });
@@ -534,7 +583,7 @@ async function signToken(claims, context) {
534
583
  throw createErrorForJWTError(e);
535
584
  }
536
585
  if (typeof output === 'undefined') {
537
- throw new TokenError({
586
+ throw new OAuth2Error({
538
587
  message: 'Invalid type.'
539
588
  });
540
589
  }
@@ -558,6 +607,9 @@ function useRedisClient() {
558
607
  }
559
608
 
560
609
  class MemoryCacheAdapter {
610
+ async has(key) {
611
+ return this.instance.has(key);
612
+ }
561
613
  async get(key) {
562
614
  return this.instance.get(key);
563
615
  }
@@ -601,6 +653,10 @@ class RedisCacheAdapter {
601
653
  async get(key) {
602
654
  return this.instance.get(key);
603
655
  }
656
+ async has(key) {
657
+ const output = await this.get(key);
658
+ return typeof output !== 'undefined';
659
+ }
604
660
  async set(key, value, options) {
605
661
  await this.instance.set(key, value, {
606
662
  milliseconds: options.ttl
@@ -689,14 +745,14 @@ function useCache() {
689
745
 
690
746
  function createLogger(context) {
691
747
  let items;
692
- const cwd = context.directory || process$1.cwd();
748
+ const cwd = context.directory || process.cwd();
693
749
  if (context.env === 'production') {
694
750
  items = [
695
751
  new transports.Console({
696
752
  level: 'info'
697
753
  }),
698
754
  new transports.File({
699
- filename: path.join(cwd, 'access.log'),
755
+ filename: path.join(cwd, 'http.log'),
700
756
  level: 'http',
701
757
  maxsize: 10 * 1024 * 1024,
702
758
  maxFiles: 5
@@ -715,6 +771,7 @@ function createLogger(context) {
715
771
  })
716
772
  ];
717
773
  }
774
+ // @see https://github.com/winstonjs/triple-beam/blob/master/config/npm.js
718
775
  return createLogger$1({
719
776
  format: format.combine(format.errors({
720
777
  stack: true
@@ -753,7 +810,7 @@ function useVaultClient() {
753
810
  }
754
811
 
755
812
  function transformDomainEventData(input) {
756
- if (isObject(input)) {
813
+ if (isObject$1(input)) {
757
814
  const keys = Object.keys(input);
758
815
  for(let i = 0; i < keys.length; i++){
759
816
  const value = input[keys[i]];
@@ -857,5 +914,5 @@ class DomainEventPublisher {
857
914
  return Object.prototype.hasOwnProperty.call(obj, prop);
858
915
  }
859
916
 
860
- export { Cache, DomainEventPublisher, DomainEventRedisPublisher, DomainEventSocketPublisher, KeyPairKind, MemoryCacheAdapter, RedisCacheAdapter, buildCacheKey, buildKeyFileName, compare, createCacheAdapter, createKeyPair, createLogger, decryptRSAPrivateKey, deleteKeyPair, extendKeyPairOptions, extractTokenHeader, extractTokenPayload, hasOwnProperty, hash, isKeyPair, isKeyPairWithPublicKey, isLoggerUsable, isRedisClientUsable, isVaultClientUsable, loadKeyPair, saveKeyPair, setLogger, setLoggerFactory, setRedisClient, setRedisFactory, setVaultFactory, signToken, unwrapPrivateKeyPem, unwrapPublicKeyPem, useCache, useKeyPair, useLogger, useRedisClient, useVaultClient, verifyToken, wrapPrivateKeyPem, wrapPublicKeyPem };
917
+ export { Cache, CryptoAsymmetricAlgorithm, CryptoKeyContainer, DomainEventPublisher, DomainEventRedisPublisher, DomainEventSocketPublisher, MemoryCacheAdapter, RedisCacheAdapter, SymmetricAlgorithm, buildCacheKey, compare, createAsymmetricKeyPair, createCacheAdapter, createLogger, createSymmetricKey, decodePemToPKCS8, decodePemToSpki, encodePKCS8ToPEM, encodeSPKIToPem, extractTokenHeader, extractTokenPayload, getKeyUsagesForAlgorithm, getKeyUsagesForAsymmetricAlgorithm, getKeyUsagesForSymmetricAlgorithm, hasOwnProperty, hash, isAsymmetricAlgorithm, isLoggerUsable, isRedisClientUsable, isSymmetricAlgorithm, isVaultClientUsable, normalizeAsymmetricKeyImportOptions, normalizeAsymmetricKeyPairCreateOptions, setLogger, setLoggerFactory, setRedisClient, setRedisFactory, setVaultFactory, signToken, useCache, useLogger, useRedisClient, useVaultClient, verifyToken };
861
918
  //# sourceMappingURL=index.mjs.map