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

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 (94) hide show
  1. package/dist/crypto/index.d.ts +3 -1
  2. package/dist/crypto/index.d.ts.map +1 -1
  3. package/dist/crypto/json-web-token/extract.d.ts +1 -1
  4. package/dist/crypto/json-web-token/extract.d.ts.map +1 -1
  5. package/dist/crypto/json-web-token/sign/module.d.ts +1 -1
  6. package/dist/crypto/json-web-token/sign/module.d.ts.map +1 -1
  7. package/dist/crypto/json-web-token/sign/types.d.ts +10 -5
  8. package/dist/crypto/json-web-token/sign/types.d.ts.map +1 -1
  9. package/dist/crypto/json-web-token/type.d.ts +1 -1
  10. package/dist/crypto/json-web-token/type.d.ts.map +1 -1
  11. package/dist/crypto/json-web-token/utils.d.ts +1 -1
  12. package/dist/crypto/json-web-token/utils.d.ts.map +1 -1
  13. package/dist/crypto/json-web-token/verify/module.d.ts +1 -1
  14. package/dist/crypto/json-web-token/verify/module.d.ts.map +1 -1
  15. package/dist/crypto/json-web-token/verify/types.d.ts +10 -5
  16. package/dist/crypto/json-web-token/verify/types.d.ts.map +1 -1
  17. package/dist/crypto/key/container.d.ts +14 -0
  18. package/dist/crypto/key/container.d.ts.map +1 -0
  19. package/dist/crypto/key/index.d.ts +3 -0
  20. package/dist/crypto/key/index.d.ts.map +1 -0
  21. package/dist/crypto/key/key-usages.d.ts +2 -0
  22. package/dist/crypto/key/key-usages.d.ts.map +1 -0
  23. package/dist/crypto/key/types.d.ts +14 -0
  24. package/dist/crypto/key/types.d.ts.map +1 -0
  25. package/dist/crypto/key-asymmetric/check.d.ts +3 -0
  26. package/dist/crypto/key-asymmetric/check.d.ts.map +1 -0
  27. package/dist/crypto/key-asymmetric/constants.d.ts +8 -0
  28. package/dist/crypto/key-asymmetric/constants.d.ts.map +1 -0
  29. package/dist/crypto/key-asymmetric/create.d.ts +3 -0
  30. package/dist/crypto/key-asymmetric/create.d.ts.map +1 -0
  31. package/dist/crypto/key-asymmetric/helpers/index.d.ts +2 -0
  32. package/dist/crypto/key-asymmetric/helpers/index.d.ts.map +1 -0
  33. package/dist/crypto/key-asymmetric/helpers/wrap.d.ts +5 -0
  34. package/dist/crypto/key-asymmetric/helpers/wrap.d.ts.map +1 -0
  35. package/dist/crypto/key-asymmetric/index.d.ts +8 -0
  36. package/dist/crypto/key-asymmetric/index.d.ts.map +1 -0
  37. package/dist/crypto/key-asymmetric/key-usages.d.ts +5 -0
  38. package/dist/crypto/key-asymmetric/key-usages.d.ts.map +1 -0
  39. package/dist/crypto/key-asymmetric/normalize.d.ts +4 -0
  40. package/dist/crypto/key-asymmetric/normalize.d.ts.map +1 -0
  41. package/dist/crypto/key-asymmetric/types.d.ts +30 -0
  42. package/dist/crypto/key-asymmetric/types.d.ts.map +1 -0
  43. package/dist/crypto/key-symmetric/check.d.ts +3 -0
  44. package/dist/crypto/key-symmetric/check.d.ts.map +1 -0
  45. package/dist/crypto/key-symmetric/constants.d.ts +7 -0
  46. package/dist/crypto/key-symmetric/constants.d.ts.map +1 -0
  47. package/dist/crypto/key-symmetric/create.d.ts +3 -0
  48. package/dist/crypto/key-symmetric/create.d.ts.map +1 -0
  49. package/dist/crypto/key-symmetric/index.d.ts +6 -0
  50. package/dist/crypto/key-symmetric/index.d.ts.map +1 -0
  51. package/dist/crypto/key-symmetric/key-usages.d.ts +2 -0
  52. package/dist/crypto/key-symmetric/key-usages.d.ts.map +1 -0
  53. package/dist/crypto/key-symmetric/normalize.d.ts +4 -0
  54. package/dist/crypto/key-symmetric/normalize.d.ts.map +1 -0
  55. package/dist/crypto/key-symmetric/types.d.ts +27 -0
  56. package/dist/crypto/key-symmetric/types.d.ts.map +1 -0
  57. package/dist/domain-event/module.d.ts +1 -1
  58. package/dist/domain-event/module.d.ts.map +1 -1
  59. package/dist/domain-event/type.d.ts +1 -1
  60. package/dist/domain-event/type.d.ts.map +1 -1
  61. package/dist/index.cjs +320 -293
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.mjs +276 -231
  64. package/dist/index.mjs.map +1 -1
  65. package/dist/services/logger/module.d.ts.map +1 -1
  66. package/package.json +14 -8
  67. package/dist/crypto/key-pair/constants.d.ts +0 -5
  68. package/dist/crypto/key-pair/constants.d.ts.map +0 -1
  69. package/dist/crypto/key-pair/create.d.ts +0 -3
  70. package/dist/crypto/key-pair/create.d.ts.map +0 -1
  71. package/dist/crypto/key-pair/delete.d.ts +0 -3
  72. package/dist/crypto/key-pair/delete.d.ts.map +0 -1
  73. package/dist/crypto/key-pair/helpers/check.d.ts +0 -4
  74. package/dist/crypto/key-pair/helpers/check.d.ts.map +0 -1
  75. package/dist/crypto/key-pair/helpers/file-name.d.ts +0 -4
  76. package/dist/crypto/key-pair/helpers/file-name.d.ts.map +0 -1
  77. package/dist/crypto/key-pair/helpers/index.d.ts +0 -6
  78. package/dist/crypto/key-pair/helpers/index.d.ts.map +0 -1
  79. package/dist/crypto/key-pair/helpers/options.d.ts +0 -3
  80. package/dist/crypto/key-pair/helpers/options.d.ts.map +0 -1
  81. package/dist/crypto/key-pair/helpers/private-key.d.ts +0 -3
  82. package/dist/crypto/key-pair/helpers/private-key.d.ts.map +0 -1
  83. package/dist/crypto/key-pair/helpers/wrap.d.ts +0 -5
  84. package/dist/crypto/key-pair/helpers/wrap.d.ts.map +0 -1
  85. package/dist/crypto/key-pair/index.d.ts +0 -9
  86. package/dist/crypto/key-pair/index.d.ts.map +0 -1
  87. package/dist/crypto/key-pair/load.d.ts +0 -3
  88. package/dist/crypto/key-pair/load.d.ts.map +0 -1
  89. package/dist/crypto/key-pair/module.d.ts +0 -3
  90. package/dist/crypto/key-pair/module.d.ts.map +0 -1
  91. package/dist/crypto/key-pair/save.d.ts +0 -3
  92. package/dist/crypto/key-pair/save.d.ts.map +0 -1
  93. package/dist/crypto/key-pair/type.d.ts +0 -64
  94. package/dist/crypto/key-pair/type.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,39 +1,20 @@
1
1
  'use strict';
2
2
 
3
3
  var bcrypt = require('@node-rs/bcrypt');
4
- var node_crypto = require('node:crypto');
5
4
  var kit = require('@authup/kit');
6
- var path = require('node:path');
7
- var fs = require('node:fs');
5
+ var specs = require('@authup/specs');
8
6
  var jsonwebtoken = require('@node-rs/jsonwebtoken');
9
7
  var smob = require('smob');
10
8
  var redisExtension = require('redis-extension');
11
9
  var singa = require('singa');
12
10
  var TTLCache = require('@isaacs/ttlcache');
13
- var process$1 = require('node:process');
11
+ var path = require('node:path');
12
+ var process = require('node:process');
14
13
  var winston = require('winston');
15
14
  var vault = require('@hapic/vault');
15
+ var coreRealtimeKit = require('@authup/core-realtime-kit');
16
16
  var redisEmitter = require('@socket.io/redis-emitter');
17
17
 
18
- function _interopNamespaceDefault(e) {
19
- var n = Object.create(null);
20
- if (e) {
21
- Object.keys(e).forEach(function (k) {
22
- if (k !== 'default') {
23
- var d = Object.getOwnPropertyDescriptor(e, k);
24
- Object.defineProperty(n, k, d.get ? d : {
25
- enumerable: true,
26
- get: function () { return e[k]; }
27
- });
28
- }
29
- });
30
- }
31
- n.default = e;
32
- return Object.freeze(n);
33
- }
34
-
35
- var process__namespace = /*#__PURE__*/_interopNamespaceDefault(process$1);
36
-
37
18
  async function compare(value, hashedValue) {
38
19
  return bcrypt.compare(value, hashedValue);
39
20
  }
@@ -47,103 +28,124 @@ async function hash(str, rounds = 10) {
47
28
  * Author Peter Placzek (tada5hi)
48
29
  * For the full copyright and license information,
49
30
  * view the LICENSE file that was distributed with this source code.
50
- */ var KeyPairKind = /*#__PURE__*/ function(KeyPairKind) {
51
- KeyPairKind["PRIVATE"] = "private";
52
- KeyPairKind["PUBLIC"] = "public";
53
- return KeyPairKind;
31
+ */ var CryptoAsymmetricAlgorithm = /*#__PURE__*/ function(CryptoAsymmetricAlgorithm) {
32
+ CryptoAsymmetricAlgorithm["RSA_PSS"] = "RSA-PSS";
33
+ CryptoAsymmetricAlgorithm["RSASSA_PKCS1_V1_5"] = "RSASSA-PKCS1-v1_5";
34
+ CryptoAsymmetricAlgorithm["RSA_OAEP"] = "RSA-OAEP";
35
+ CryptoAsymmetricAlgorithm["ECDSA"] = "ECDSA";
36
+ CryptoAsymmetricAlgorithm["ECDH"] = "ECDH";
37
+ return CryptoAsymmetricAlgorithm;
54
38
  }({});
55
39
 
56
- function isKeyPair(data) {
57
- return kit.isObject(data) && typeof data.privateKey !== 'undefined' && typeof data.publicKey !== 'undefined';
58
- }
59
- function isKeyPairWithPublicKey(data) {
60
- return kit.isObject(data) && typeof data.publicKey !== 'undefined';
40
+ function isAsymmetricAlgorithm(input) {
41
+ return Object.values(CryptoAsymmetricAlgorithm).indexOf(input) !== -1;
61
42
  }
62
43
 
63
- function extendKeyPairOptions(options) {
64
- var _options;
65
- options = options ?? {};
66
- options.directory = options.directory || process.cwd();
67
- options.directory = path.isAbsolute(options.directory) ? options.directory : path.resolve(process.cwd(), options.directory);
68
- (_options = options).type ?? (_options.type = 'rsa');
69
- if (options.type === 'rsa' || options.type === 'rsa-pss' || options.type === 'dsa') {
70
- options.modulusLength = 2048;
71
- }
72
- if (!options.privateKeyEncoding) {
73
- options.privateKeyEncoding = {
74
- type: 'pkcs8',
75
- format: 'pem'
76
- };
44
+ /**
45
+ * @see https://nodejs.org/api/webcrypto.html#cryptokeyusages
46
+ */ function getKeyUsagesForAsymmetricAlgorithm(name, format) {
47
+ if (name === CryptoAsymmetricAlgorithm.RSA_PSS || name === CryptoAsymmetricAlgorithm.ECDSA || name === CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5) {
48
+ if (format === 'spki') {
49
+ return [
50
+ 'verify'
51
+ ];
52
+ }
53
+ if (format === 'pkcs8') {
54
+ return [
55
+ 'sign'
56
+ ];
57
+ }
58
+ return [
59
+ 'sign',
60
+ 'verify'
61
+ ];
77
62
  }
78
- if (!options.publicKeyEncoding) {
79
- options.publicKeyEncoding = {
80
- type: 'spki',
81
- format: 'pem'
82
- };
63
+ if (name === CryptoAsymmetricAlgorithm.ECDH) {
64
+ if (format === 'spki') {
65
+ return [];
66
+ }
67
+ return [
68
+ 'deriveKey',
69
+ 'deriveBits'
70
+ ];
83
71
  }
84
- if (options.privateKeyEncoding.passphrase && !options.privateKeyEncoding.cipher) {
85
- options.privateKeyEncoding.cipher = 'aes-256-cbc';
72
+ if (name === CryptoAsymmetricAlgorithm.RSA_OAEP) {
73
+ if (format === 'spki') {
74
+ return [
75
+ 'encrypt'
76
+ ];
77
+ }
78
+ if (format === 'pkcs8') {
79
+ return [
80
+ 'decrypt'
81
+ ];
82
+ }
83
+ return [
84
+ 'encrypt',
85
+ 'decrypt'
86
+ ];
86
87
  }
87
- return options;
88
+ throw new SyntaxError(`Key usages can not be determined for asymmetric algorithm: ${name}`);
88
89
  }
89
90
 
90
- function buildKeyFileName(type, context) {
91
- const options = extendKeyPairOptions(context);
92
- const parts = [];
93
- switch(type){
94
- case KeyPairKind.PRIVATE:
91
+ function normalizeAsymmetricKeyPairCreateOptions(options) {
92
+ let optionsNormalized;
93
+ switch(options.name){
94
+ case CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5:
95
+ case CryptoAsymmetricAlgorithm.RSA_PSS:
96
+ case CryptoAsymmetricAlgorithm.RSA_OAEP:
95
97
  {
96
- if (options.privateName) {
97
- parts.push(options.privateName);
98
- } else {
99
- parts.push(type);
100
- }
101
- if (options.privateExtension) {
102
- if (options.privateExtension.startsWith('.')) {
103
- options.privateExtension = options.privateExtension.slice(1);
104
- }
105
- parts.push(options.privateExtension);
106
- } else {
107
- parts.push('pem');
108
- }
98
+ optionsNormalized = {
99
+ modulusLength: 2048,
100
+ publicExponent: new Uint8Array([
101
+ 0x01,
102
+ 0x00,
103
+ 0x01
104
+ ]),
105
+ hash: 'SHA-256',
106
+ ...options
107
+ };
109
108
  break;
110
109
  }
111
- case KeyPairKind.PUBLIC:
110
+ case CryptoAsymmetricAlgorithm.ECDSA:
111
+ case CryptoAsymmetricAlgorithm.ECDH:
112
112
  {
113
- if (options.publicName) {
114
- parts.push(options.publicName);
115
- } else {
116
- parts.push(type);
117
- }
118
- if (options.publicExtension) {
119
- if (options.publicExtension.startsWith('.')) {
120
- options.publicExtension = options.publicExtension.slice(1);
121
- }
122
- parts.push(options.publicExtension);
123
- } else {
124
- parts.push('pem');
125
- }
113
+ optionsNormalized = {
114
+ namedCurve: 'P-256',
115
+ ...options
116
+ };
117
+ }
118
+ }
119
+ return optionsNormalized;
120
+ }
121
+ function normalizeAsymmetricKeyImportOptions(options) {
122
+ let optionsNormalized;
123
+ switch(options.name){
124
+ case CryptoAsymmetricAlgorithm.RSASSA_PKCS1_V1_5:
125
+ case CryptoAsymmetricAlgorithm.RSA_PSS:
126
+ case CryptoAsymmetricAlgorithm.RSA_OAEP:
127
+ {
128
+ optionsNormalized = {
129
+ hash: 'SHA-256',
130
+ ...options
131
+ };
126
132
  break;
127
133
  }
134
+ case CryptoAsymmetricAlgorithm.ECDSA:
135
+ case CryptoAsymmetricAlgorithm.ECDH:
136
+ {
137
+ optionsNormalized = {
138
+ namedCurve: 'P-256',
139
+ ...options
140
+ };
141
+ }
128
142
  }
129
- return parts.join('.');
143
+ return optionsNormalized;
130
144
  }
131
145
 
132
- function decryptRSAPrivateKey(context, key) {
133
- const privateKey = node_crypto.createPrivateKey({
134
- type: context.privateKeyEncoding.type,
135
- format: context.privateKeyEncoding.format,
136
- key,
137
- passphrase: context.privateKeyEncoding.passphrase || context.passphrase
138
- });
139
- let content = privateKey.export({
140
- type: context.privateKeyEncoding.type,
141
- format: context.privateKeyEncoding.format
142
- });
143
- if (typeof content !== 'string') {
144
- content = Buffer.from(content).toString('utf-8');
145
- }
146
- return content;
146
+ async function createAsymmetricKeyPair(options) {
147
+ const optionsNormalized = normalizeAsymmetricKeyPairCreateOptions(options);
148
+ return crypto.subtle.generateKey(optionsNormalized, true, getKeyUsagesForAsymmetricAlgorithm(optionsNormalized.name));
147
149
  }
148
150
 
149
151
  /*
@@ -151,172 +153,169 @@ function decryptRSAPrivateKey(context, key) {
151
153
  * Author Peter Placzek (tada5hi)
152
154
  * For the full copyright and license information,
153
155
  * view the LICENSE file that was distributed with this source code.
154
- */ function wrapPem(type, input) {
155
- if (typeof input !== 'string') {
156
- input = Buffer.from(input).toString('base64');
157
- }
156
+ */ function enc(type, input) {
158
157
  return `-----BEGIN ${type}-----\n${input}\n-----END ${type}-----`;
159
158
  }
160
- function wrapPrivateKeyPem(input) {
161
- return wrapPem('PRIVATE KEY', input);
159
+ function encodePKCS8ToPEM(base64) {
160
+ return enc('PRIVATE KEY', base64);
162
161
  }
163
- function wrapPublicKeyPem(input) {
164
- return wrapPem('PUBLIC KEY', input);
162
+ function encodeSPKIToPem(input) {
163
+ return enc('PUBLIC KEY', input);
165
164
  }
166
165
  // ------------------------------------------------------------
167
- function unwrapPem(type, input) {
168
- if (typeof input !== 'string') {
169
- input = Buffer.from(input).toString('base64');
170
- }
166
+ function dec(type, input) {
171
167
  input = input.replace(`-----BEGIN ${type}-----\n`, '');
172
168
  input = input.replace(`\n-----END ${type}-----\n`, '');
173
169
  input = input.replace(`-----END ${type}-----\n`, '');
174
170
  input = input.replace(`\n-----END ${type}-----`, '');
175
171
  return input;
176
172
  }
177
- function unwrapPrivateKeyPem(input) {
178
- return unwrapPem('PRIVATE KEY', input);
173
+ function decodePemToPKCS8(input) {
174
+ return dec('PRIVATE KEY', input);
179
175
  }
180
- function unwrapPublicKeyPem(input) {
181
- return unwrapPem('PUBLIC KEY', input);
176
+ function decodePemToSpki(input) {
177
+ return dec('PUBLIC KEY', input);
182
178
  }
183
179
 
184
- async function saveKeyPair(keyPair, context) {
185
- context = extendKeyPairOptions(context);
186
- await fs.promises.mkdir(context.directory, {
187
- recursive: true
188
- });
189
- await Promise.all([
190
- {
191
- path: path.resolve(context.directory, buildKeyFileName(KeyPairKind.PRIVATE, context)),
192
- content: keyPair.privateKey
193
- },
194
- {
195
- path: path.resolve(context.directory, buildKeyFileName(KeyPairKind.PUBLIC, context)),
196
- content: keyPair.publicKey
197
- }
198
- ].map((file)=>fs.promises.writeFile(file.path, file.content)));
199
- return keyPair;
200
- }
201
-
202
- async function createKeyPair(context) {
203
- const options = extendKeyPairOptions(context);
204
- const keyPair = await new Promise((resolve, reject)=>{
205
- const callback = (err, publicKey, privateKey)=>{
206
- if (err) reject(err);
207
- resolve({
208
- privateKey,
209
- publicKey
210
- });
180
+ /*
181
+ * Copyright (c) 2024.
182
+ * Author Peter Placzek (tada5hi)
183
+ * For the full copyright and license information,
184
+ * view the LICENSE file that was distributed with this source code.
185
+ */ var SymmetricAlgorithm = /*#__PURE__*/ function(SymmetricAlgorithm) {
186
+ SymmetricAlgorithm["HMAC"] = "HMAC";
187
+ SymmetricAlgorithm["AES_CTR"] = "AES-CTR";
188
+ SymmetricAlgorithm["AES_CBC"] = "AES-CBC";
189
+ SymmetricAlgorithm["AES_GCM"] = "AES-GCM";
190
+ return SymmetricAlgorithm;
191
+ }({});
192
+
193
+ function normalizeSymmetricKeyCreateOptions(input) {
194
+ if (input.name === SymmetricAlgorithm.HMAC) {
195
+ return {
196
+ hash: 'SHA-256',
197
+ ...input
211
198
  };
212
- switch(options.type){
213
- case 'dsa':
214
- node_crypto.generateKeyPair(options.type, options, callback);
215
- break;
216
- case 'ec':
217
- node_crypto.generateKeyPair(options.type, options, callback);
218
- break;
219
- case 'rsa':
220
- node_crypto.generateKeyPair(options.type, options, callback);
221
- break;
222
- case 'rsa-pss':
223
- node_crypto.generateKeyPair(options.type, options, callback);
224
- break;
225
- }
226
- });
227
- if (options.save) {
228
- await saveKeyPair(keyPair, options);
229
199
  }
230
- if (options.passphrase || options.privateKeyEncoding.passphrase) {
231
- keyPair.privateKey = decryptRSAPrivateKey(options, keyPair.privateKey);
200
+ return {
201
+ length: 256,
202
+ name: input.name
203
+ };
204
+ }
205
+ function normalizeSymmetricKeyImportOptions(input) {
206
+ if (input.name === SymmetricAlgorithm.HMAC) {
207
+ return {
208
+ hash: 'SHA-256',
209
+ ...input
210
+ };
232
211
  }
233
- return keyPair;
212
+ return input;
234
213
  }
235
214
 
236
- async function deleteKeyPair(context) {
237
- const options = extendKeyPairOptions(context);
238
- const privateKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PRIVATE, options));
239
- const publicKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PUBLIC, options));
240
- try {
241
- await Promise.all([
242
- privateKeyPath,
243
- publicKeyPath
244
- ].map((filePath)=>fs.promises.stat(filePath)));
245
- } catch (e) {
246
- return;
215
+ function isSymmetricAlgorithm(input) {
216
+ return Object.values(SymmetricAlgorithm).indexOf(input) !== -1;
217
+ }
218
+
219
+ function getKeyUsagesForSymmetricAlgorithm(name) {
220
+ /**
221
+ * @see https://nodejs.org/api/webcrypto.html#cryptokeyusages
222
+ */ if (name === SymmetricAlgorithm.HMAC) {
223
+ return [
224
+ 'sign',
225
+ 'verify'
226
+ ];
227
+ }
228
+ if (name === SymmetricAlgorithm.AES_CBC || name === SymmetricAlgorithm.AES_GCM || name === SymmetricAlgorithm.AES_CTR) {
229
+ return [
230
+ 'encrypt',
231
+ 'decrypt'
232
+ ];
247
233
  }
248
- await Promise.all([
249
- privateKeyPath,
250
- publicKeyPath
251
- ].map((filePath)=>fs.promises.rm(filePath)));
234
+ throw new SyntaxError(`Key usages can not be determined for symmetric algorithm: ${name}`);
252
235
  }
253
236
 
254
- async function loadKeyPair(context) {
255
- const options = extendKeyPairOptions(context);
256
- const privateKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PRIVATE, options));
257
- try {
258
- await fs.promises.stat(privateKeyPath);
259
- } catch (e) {
260
- return undefined;
237
+ async function createSymmetricKey(input) {
238
+ const optionsNormalized = normalizeSymmetricKeyCreateOptions(input);
239
+ return crypto.subtle.generateKey(optionsNormalized, true, getKeyUsagesForSymmetricAlgorithm(optionsNormalized.name));
240
+ }
241
+
242
+ function getKeyUsagesForAlgorithm(name, format) {
243
+ if (isAsymmetricAlgorithm(name)) {
244
+ return getKeyUsagesForAsymmetricAlgorithm(name, format);
261
245
  }
262
- const privateKeyBuffer = await fs.promises.readFile(privateKeyPath);
263
- let privateKey = privateKeyBuffer.toString();
264
- if (options.passphrase || options.privateKeyEncoding.passphrase) {
265
- privateKey = decryptRSAPrivateKey(options, privateKey);
246
+ if (isSymmetricAlgorithm(name)) {
247
+ return getKeyUsagesForSymmetricAlgorithm(name);
266
248
  }
267
- const publicKeyPath = path.resolve(options.directory, buildKeyFileName(KeyPairKind.PUBLIC, options));
268
- let publicKey;
269
- try {
270
- await fs.promises.stat(publicKeyPath);
271
- const publicKeyBuffer = await fs.promises.readFile(publicKeyPath);
272
- publicKey = publicKeyBuffer.toString();
273
- } catch (e) {
274
- const publicKeyObject = node_crypto.createPublicKey({
275
- key: privateKey,
276
- format: options.privateKeyEncoding.format,
277
- type: options.publicKeyEncoding.type
278
- });
279
- const stringOrBuffer = publicKeyObject.export({
280
- format: options.publicKeyEncoding.format,
281
- type: options.publicKeyEncoding.type
282
- });
283
- if (typeof stringOrBuffer !== 'string') {
284
- publicKey = stringOrBuffer.toString();
285
- } else {
286
- publicKey = stringOrBuffer;
249
+ throw new SyntaxError(`Key usages can not be determined for algorithm: ${name}`);
250
+ }
251
+
252
+ class CryptoKeyContainer {
253
+ // ----------------------------------------------
254
+ async toArrayBuffer() {
255
+ if (this.key.type === 'private') {
256
+ return crypto.subtle.exportKey('pkcs8', this.key);
287
257
  }
288
- if (options.save) {
289
- await saveKeyPair({
290
- privateKey,
291
- publicKey
292
- }, options);
258
+ if (this.key.type === 'public') {
259
+ return crypto.subtle.exportKey('spki', this.key);
293
260
  }
261
+ return crypto.subtle.exportKey('raw', this.key);
294
262
  }
295
- return {
296
- privateKey,
297
- publicKey
298
- };
299
- }
300
-
301
- const keyPairCache = {};
302
- async function useKeyPair(value) {
303
- let options;
304
- if (typeof value === 'string') {
305
- options = extendKeyPairOptions({
306
- privateName: value
263
+ async toUint8Array() {
264
+ const arrayBuffer = await this.toArrayBuffer();
265
+ return new Uint8Array(arrayBuffer);
266
+ }
267
+ async toBase64() {
268
+ const arrayBuffer = await this.toArrayBuffer();
269
+ return kit.arrayBufferToBase64(arrayBuffer);
270
+ }
271
+ async toPem() {
272
+ const base64 = await this.toBase64();
273
+ if (this.key.type === 'public') {
274
+ return encodeSPKIToPem(base64);
275
+ }
276
+ if (this.key.type === 'private') {
277
+ return encodePKCS8ToPEM(base64);
278
+ }
279
+ throw new Error('A symmetric key can not be encoded as PEM');
280
+ }
281
+ async toJWK() {
282
+ return crypto.subtle.exportKey('jwk', this.key);
283
+ }
284
+ // ----------------------------------------------
285
+ static async fromPem(ctx) {
286
+ if (ctx.format === 'pkcs8') {
287
+ return CryptoKeyContainer.fromBase64({
288
+ ...ctx,
289
+ key: decodePemToPKCS8(ctx.key)
290
+ });
291
+ }
292
+ return CryptoKeyContainer.fromBase64({
293
+ ...ctx,
294
+ key: decodePemToSpki(ctx.key)
307
295
  });
308
- } else {
309
- options = extendKeyPairOptions(value || {});
310
296
  }
311
- if (Object.prototype.hasOwnProperty.call(keyPairCache, options.privateName)) {
312
- return keyPairCache[options.privateName];
297
+ static async fromBase64(ctx) {
298
+ const arrayBuffer = kit.base64ToArrayBuffer(ctx.key);
299
+ return CryptoKeyContainer.fromArrayBuffer({
300
+ ...ctx,
301
+ key: arrayBuffer
302
+ });
313
303
  }
314
- let keyPair = await loadKeyPair(options);
315
- if (typeof keyPair === 'undefined') {
316
- keyPair = await createKeyPair(options);
304
+ static async fromArrayBuffer(ctx) {
305
+ let normalizedOptions;
306
+ if (ctx.format === 'spki' || ctx.format === 'pkcs8') {
307
+ normalizedOptions = normalizeAsymmetricKeyImportOptions(ctx.options);
308
+ } else if (ctx.format === 'raw') {
309
+ normalizedOptions = normalizeSymmetricKeyImportOptions(ctx.options);
310
+ } else {
311
+ throw new SyntaxError(`Format ${ctx.format} is not supported.`);
312
+ }
313
+ const cryptoKey = await crypto.subtle.importKey(ctx.format, ctx.key, normalizedOptions, true, getKeyUsagesForAlgorithm(normalizedOptions.name, ctx.format));
314
+ return new CryptoKeyContainer(cryptoKey);
315
+ }
316
+ constructor(cryptoKey){
317
+ this.key = cryptoKey;
317
318
  }
318
- keyPairCache[options.privateName] = keyPair;
319
- return keyPair;
320
319
  }
321
320
 
322
321
  /**
@@ -328,7 +327,7 @@ async function useKeyPair(value) {
328
327
  */ function extractTokenHeader(token) {
329
328
  const parts = token.split('.');
330
329
  if (parts.length !== 3) {
331
- throw kit.TokenError.payloadInvalid('The token format is not valid.');
330
+ throw specs.TokenError.payloadInvalid('The token format is not valid.');
332
331
  }
333
332
  const [headerBase64] = parts;
334
333
  try {
@@ -347,20 +346,20 @@ async function useKeyPair(value) {
347
346
  'x5t#S256': header.x5TS256CertThumbprint,
348
347
  };
349
348
  */ } catch (e) {
350
- throw kit.TokenError.headerInvalid('The token header could not be extracted.');
349
+ throw specs.TokenError.headerInvalid('The token header could not be extracted.');
351
350
  }
352
351
  }
353
352
  function extractTokenPayload(token) {
354
353
  const parts = token.split('.');
355
354
  if (parts.length !== 3) {
356
- throw kit.TokenError.payloadInvalid('The token format is not valid.');
355
+ throw specs.TokenError.payloadInvalid('The token format is not valid.');
357
356
  }
358
357
  const [, payloadBase64] = parts;
359
358
  try {
360
359
  const payload = atob(payloadBase64);
361
360
  return JSON.parse(payload);
362
361
  } catch (e) {
363
- throw kit.TokenError.payloadInvalid('The token payload could not be extracted.');
362
+ throw specs.TokenError.payloadInvalid('The token payload could not be extracted.');
364
363
  }
365
364
  }
366
365
 
@@ -370,19 +369,19 @@ function createErrorForJWTError(e) {
370
369
  switch(e.name){
371
370
  case 'TokenExpiredError':
372
371
  {
373
- return kit.TokenError.expired();
372
+ return specs.TokenError.expired();
374
373
  }
375
374
  case 'NotBeforeError':
376
375
  {
377
376
  if (typeof e.date === 'string' || e.date instanceof Date) {
378
- return kit.TokenError.notActiveBefore(e.date);
377
+ return specs.TokenError.notActiveBefore(e.date);
379
378
  }
380
379
  break;
381
380
  }
382
381
  case 'JsonWebTokenError':
383
382
  {
384
383
  if (typeof e.message === 'string') {
385
- return kit.TokenError.payloadInvalid(e.message);
384
+ return specs.TokenError.payloadInvalid(e.message);
386
385
  }
387
386
  break;
388
387
  }
@@ -392,20 +391,20 @@ function createErrorForJWTError(e) {
392
391
  switch(e.message){
393
392
  case 'ExpiredSignature':
394
393
  {
395
- return kit.TokenError.expired();
394
+ return specs.TokenError.expired();
396
395
  }
397
396
  case 'ImmatureSignature':
398
397
  {
399
- return kit.TokenError.notActiveBefore();
398
+ return specs.TokenError.notActiveBefore();
400
399
  }
401
400
  case 'InvalidToken':
402
401
  case 'InvalidSignature':
403
402
  {
404
- return kit.TokenError.payloadInvalid();
403
+ return specs.TokenError.payloadInvalid();
405
404
  }
406
405
  }
407
406
  }
408
- return new kit.TokenError({
407
+ return new specs.TokenError({
409
408
  cause: e,
410
409
  logMessage: true,
411
410
  message: 'The JWT error could not be determined.'
@@ -413,47 +412,47 @@ function createErrorForJWTError(e) {
413
412
  }
414
413
  function transformJWTAlgorithmToInternal(algorithm) {
415
414
  switch(algorithm){
416
- case kit.JWTAlgorithm.HS256:
415
+ case specs.JWTAlgorithm.HS256:
417
416
  {
418
417
  return jsonwebtoken.Algorithm.HS256;
419
418
  }
420
- case kit.JWTAlgorithm.HS384:
419
+ case specs.JWTAlgorithm.HS384:
421
420
  {
422
421
  return jsonwebtoken.Algorithm.HS384;
423
422
  }
424
- case kit.JWTAlgorithm.HS512:
423
+ case specs.JWTAlgorithm.HS512:
425
424
  {
426
425
  return jsonwebtoken.Algorithm.HS512;
427
426
  }
428
- case kit.JWTAlgorithm.RS256:
427
+ case specs.JWTAlgorithm.RS256:
429
428
  {
430
429
  return jsonwebtoken.Algorithm.RS256;
431
430
  }
432
- case kit.JWTAlgorithm.RS384:
431
+ case specs.JWTAlgorithm.RS384:
433
432
  {
434
433
  return jsonwebtoken.Algorithm.RS384;
435
434
  }
436
- case kit.JWTAlgorithm.RS512:
435
+ case specs.JWTAlgorithm.RS512:
437
436
  {
438
437
  return jsonwebtoken.Algorithm.RS512;
439
438
  }
440
- case kit.JWTAlgorithm.ES256:
439
+ case specs.JWTAlgorithm.ES256:
441
440
  {
442
441
  return jsonwebtoken.Algorithm.ES256;
443
442
  }
444
- case kit.JWTAlgorithm.ES384:
443
+ case specs.JWTAlgorithm.ES384:
445
444
  {
446
445
  return jsonwebtoken.Algorithm.ES384;
447
446
  }
448
- case kit.JWTAlgorithm.PS256:
447
+ case specs.JWTAlgorithm.PS256:
449
448
  {
450
449
  return jsonwebtoken.Algorithm.PS256;
451
450
  }
452
- case kit.JWTAlgorithm.PS384:
451
+ case specs.JWTAlgorithm.PS384:
453
452
  {
454
453
  return jsonwebtoken.Algorithm.PS384;
455
454
  }
456
- case kit.JWTAlgorithm.PS512:
455
+ case specs.JWTAlgorithm.PS512:
457
456
  {
458
457
  return jsonwebtoken.Algorithm.PS512;
459
458
  }
@@ -470,31 +469,44 @@ async function signToken(claims, context) {
470
469
  claims.iat = getUtcTimestamp();
471
470
  }
472
471
  switch(context.type){
473
- case kit.JWKType.RSA:
474
- case kit.JWKType.EC:
472
+ case specs.JWKType.RSA:
473
+ case specs.JWKType.EC:
475
474
  {
476
- const { privateKey } = isKeyPair(context.keyPair) ? context.keyPair : await useKeyPair(context.keyPair);
477
475
  let algorithm;
478
- if (context.type === kit.JWKType.RSA) {
476
+ let key;
477
+ if (typeof context.key === 'string') {
478
+ key = encodePKCS8ToPEM(context.key);
479
+ } else {
480
+ const keyContainer = new CryptoKeyContainer(context.key);
481
+ key = await keyContainer.toPem();
482
+ }
483
+ if (context.type === specs.JWKType.RSA) {
479
484
  algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : jsonwebtoken.Algorithm.RS256;
480
485
  } else {
481
486
  algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : jsonwebtoken.Algorithm.ES256;
482
487
  }
483
- return jsonwebtoken.sign(claims, privateKey, {
488
+ return jsonwebtoken.sign(claims, key, {
484
489
  algorithm,
485
490
  keyId: context.keyId
486
491
  });
487
492
  }
488
- case kit.JWKType.OCT:
493
+ case specs.JWKType.OCT:
489
494
  {
490
495
  const algorithm = context.algorithm ? transformJWTAlgorithmToInternal(context.algorithm) : jsonwebtoken.Algorithm.HS256;
491
- return jsonwebtoken.sign(claims, context.key, {
496
+ let key;
497
+ if (typeof context.key === 'string') {
498
+ key = context.key;
499
+ } else {
500
+ const keyContainer = new CryptoKeyContainer(context.key);
501
+ key = await keyContainer.toUint8Array();
502
+ }
503
+ return jsonwebtoken.sign(claims, key, {
492
504
  algorithm,
493
505
  keyId: context.keyId
494
506
  });
495
507
  }
496
508
  }
497
- throw new kit.TokenError();
509
+ throw new specs.TokenError();
498
510
  }
499
511
 
500
512
  /**
@@ -509,12 +521,11 @@ async function signToken(claims, context) {
509
521
  let output;
510
522
  try {
511
523
  switch(context.type){
512
- case kit.JWKType.RSA:
513
- case kit.JWKType.EC:
524
+ case specs.JWKType.RSA:
525
+ case specs.JWKType.EC:
514
526
  {
515
- const { publicKey } = isKeyPairWithPublicKey(context.keyPair) ? context.keyPair : await useKeyPair(context.keyPair);
516
527
  let algorithms;
517
- if (context.type === kit.JWKType.RSA) {
528
+ if (context.type === specs.JWKType.RSA) {
518
529
  algorithms = context.algorithms ? context.algorithms.map((algorithm)=>transformJWTAlgorithmToInternal(algorithm)) : [
519
530
  jsonwebtoken.Algorithm.RS256,
520
531
  jsonwebtoken.Algorithm.RS384,
@@ -529,20 +540,34 @@ async function signToken(claims, context) {
529
540
  jsonwebtoken.Algorithm.ES384
530
541
  ];
531
542
  }
532
- promise = jsonwebtoken.verify(token, publicKey, {
543
+ let key;
544
+ if (typeof context.key === 'string') {
545
+ key = encodeSPKIToPem(context.key);
546
+ } else {
547
+ const keyContainer = new CryptoKeyContainer(context.key);
548
+ key = await keyContainer.toPem();
549
+ }
550
+ promise = jsonwebtoken.verify(token, key, {
533
551
  algorithms,
534
552
  validateNbf: true
535
553
  });
536
554
  break;
537
555
  }
538
- case kit.JWKType.OCT:
556
+ case specs.JWKType.OCT:
539
557
  {
540
558
  const algorithms = context.algorithms ? context.algorithms.map((algorithm)=>transformJWTAlgorithmToInternal(algorithm)) : [
541
559
  jsonwebtoken.Algorithm.HS256,
542
560
  jsonwebtoken.Algorithm.HS384,
543
561
  jsonwebtoken.Algorithm.HS512
544
562
  ];
545
- promise = jsonwebtoken.verify(token, context.key, {
563
+ let key;
564
+ if (typeof context.key === 'string') {
565
+ key = context.key;
566
+ } else {
567
+ const keyContainer = new CryptoKeyContainer(context.key);
568
+ key = await keyContainer.toUint8Array();
569
+ }
570
+ promise = jsonwebtoken.verify(token, key, {
546
571
  algorithms,
547
572
  validateNbf: true
548
573
  });
@@ -553,7 +578,7 @@ async function signToken(claims, context) {
553
578
  throw createErrorForJWTError(e);
554
579
  }
555
580
  if (typeof output === 'undefined') {
556
- throw new kit.TokenError({
581
+ throw new specs.TokenError({
557
582
  message: 'Invalid type.'
558
583
  });
559
584
  }
@@ -708,14 +733,14 @@ function useCache() {
708
733
 
709
734
  function createLogger(context) {
710
735
  let items;
711
- const cwd = context.directory || process__namespace.cwd();
736
+ const cwd = context.directory || process.cwd();
712
737
  if (context.env === 'production') {
713
738
  items = [
714
739
  new winston.transports.Console({
715
740
  level: 'info'
716
741
  }),
717
742
  new winston.transports.File({
718
- filename: path.join(cwd, 'access.log'),
743
+ filename: path.join(cwd, 'http.log'),
719
744
  level: 'http',
720
745
  maxsize: 10 * 1024 * 1024,
721
746
  maxFiles: 5
@@ -734,6 +759,7 @@ function createLogger(context) {
734
759
  })
735
760
  ];
736
761
  }
762
+ // @see https://github.com/winstonjs/triple-beam/blob/master/config/npm.js
737
763
  return winston.createLogger({
738
764
  format: winston.format.combine(winston.format.errors({
739
765
  stack: true
@@ -822,7 +848,7 @@ class DomainEventSocketPublisher {
822
848
  emitter = this.driver;
823
849
  }
824
850
  let roomName = buildDomainEventChannelName(ctx.destinations[i].channel);
825
- const fullEventName = kit.buildEventFullName(ctx.content.type, ctx.content.event);
851
+ const fullEventName = coreRealtimeKit.buildEventFullName(ctx.content.type, ctx.content.event);
826
852
  emitter.in(roomName).emit(fullEventName, {
827
853
  ...ctx.content,
828
854
  meta: {
@@ -921,46 +947,47 @@ Object.defineProperty(exports, "createVaultClient", {
921
947
  get: function () { return vault.createClient; }
922
948
  });
923
949
  exports.Cache = Cache;
950
+ exports.CryptoAsymmetricAlgorithm = CryptoAsymmetricAlgorithm;
951
+ exports.CryptoKeyContainer = CryptoKeyContainer;
924
952
  exports.DomainEventPublisher = DomainEventPublisher;
925
953
  exports.DomainEventRedisPublisher = DomainEventRedisPublisher;
926
954
  exports.DomainEventSocketPublisher = DomainEventSocketPublisher;
927
- exports.KeyPairKind = KeyPairKind;
928
955
  exports.MemoryCacheAdapter = MemoryCacheAdapter;
929
956
  exports.RedisCacheAdapter = RedisCacheAdapter;
957
+ exports.SymmetricAlgorithm = SymmetricAlgorithm;
930
958
  exports.buildCacheKey = buildCacheKey;
931
- exports.buildKeyFileName = buildKeyFileName;
932
959
  exports.compare = compare;
960
+ exports.createAsymmetricKeyPair = createAsymmetricKeyPair;
933
961
  exports.createCacheAdapter = createCacheAdapter;
934
- exports.createKeyPair = createKeyPair;
935
962
  exports.createLogger = createLogger;
936
- exports.decryptRSAPrivateKey = decryptRSAPrivateKey;
937
- exports.deleteKeyPair = deleteKeyPair;
938
- exports.extendKeyPairOptions = extendKeyPairOptions;
963
+ exports.createSymmetricKey = createSymmetricKey;
964
+ exports.decodePemToPKCS8 = decodePemToPKCS8;
965
+ exports.decodePemToSpki = decodePemToSpki;
966
+ exports.encodePKCS8ToPEM = encodePKCS8ToPEM;
967
+ exports.encodeSPKIToPem = encodeSPKIToPem;
939
968
  exports.extractTokenHeader = extractTokenHeader;
940
969
  exports.extractTokenPayload = extractTokenPayload;
970
+ exports.getKeyUsagesForAlgorithm = getKeyUsagesForAlgorithm;
971
+ exports.getKeyUsagesForAsymmetricAlgorithm = getKeyUsagesForAsymmetricAlgorithm;
972
+ exports.getKeyUsagesForSymmetricAlgorithm = getKeyUsagesForSymmetricAlgorithm;
941
973
  exports.hasOwnProperty = hasOwnProperty;
942
974
  exports.hash = hash;
943
- exports.isKeyPair = isKeyPair;
944
- exports.isKeyPairWithPublicKey = isKeyPairWithPublicKey;
975
+ exports.isAsymmetricAlgorithm = isAsymmetricAlgorithm;
945
976
  exports.isLoggerUsable = isLoggerUsable;
946
977
  exports.isRedisClientUsable = isRedisClientUsable;
978
+ exports.isSymmetricAlgorithm = isSymmetricAlgorithm;
947
979
  exports.isVaultClientUsable = isVaultClientUsable;
948
- exports.loadKeyPair = loadKeyPair;
949
- exports.saveKeyPair = saveKeyPair;
980
+ exports.normalizeAsymmetricKeyImportOptions = normalizeAsymmetricKeyImportOptions;
981
+ exports.normalizeAsymmetricKeyPairCreateOptions = normalizeAsymmetricKeyPairCreateOptions;
950
982
  exports.setLogger = setLogger;
951
983
  exports.setLoggerFactory = setLoggerFactory;
952
984
  exports.setRedisClient = setRedisClient;
953
985
  exports.setRedisFactory = setRedisFactory;
954
986
  exports.setVaultFactory = setVaultFactory;
955
987
  exports.signToken = signToken;
956
- exports.unwrapPrivateKeyPem = unwrapPrivateKeyPem;
957
- exports.unwrapPublicKeyPem = unwrapPublicKeyPem;
958
988
  exports.useCache = useCache;
959
- exports.useKeyPair = useKeyPair;
960
989
  exports.useLogger = useLogger;
961
990
  exports.useRedisClient = useRedisClient;
962
991
  exports.useVaultClient = useVaultClient;
963
992
  exports.verifyToken = verifyToken;
964
- exports.wrapPrivateKeyPem = wrapPrivateKeyPem;
965
- exports.wrapPublicKeyPem = wrapPublicKeyPem;
966
993
  //# sourceMappingURL=index.cjs.map