@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.
- package/LICENSE +1 -1
- package/dist/crypto/index.d.ts +3 -1
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/json-web-token/extract.d.ts +7 -2
- package/dist/crypto/json-web-token/extract.d.ts.map +1 -1
- package/dist/crypto/json-web-token/sign/module.d.ts +1 -1
- package/dist/crypto/json-web-token/sign/module.d.ts.map +1 -1
- package/dist/crypto/json-web-token/sign/types.d.ts +10 -5
- package/dist/crypto/json-web-token/sign/types.d.ts.map +1 -1
- package/dist/crypto/json-web-token/type.d.ts +1 -1
- package/dist/crypto/json-web-token/type.d.ts.map +1 -1
- package/dist/crypto/json-web-token/utils.d.ts +2 -2
- package/dist/crypto/json-web-token/utils.d.ts.map +1 -1
- package/dist/crypto/json-web-token/verify/module.d.ts +2 -2
- package/dist/crypto/json-web-token/verify/module.d.ts.map +1 -1
- package/dist/crypto/json-web-token/verify/types.d.ts +10 -5
- package/dist/crypto/json-web-token/verify/types.d.ts.map +1 -1
- package/dist/crypto/key/container.d.ts +14 -0
- package/dist/crypto/key/container.d.ts.map +1 -0
- package/dist/crypto/key/index.d.ts +3 -0
- package/dist/crypto/key/index.d.ts.map +1 -0
- package/dist/crypto/key/key-usages.d.ts +2 -0
- package/dist/crypto/key/key-usages.d.ts.map +1 -0
- package/dist/crypto/key/types.d.ts +14 -0
- package/dist/crypto/key/types.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/check.d.ts +3 -0
- package/dist/crypto/key-asymmetric/check.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/constants.d.ts +8 -0
- package/dist/crypto/key-asymmetric/constants.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/create.d.ts +3 -0
- package/dist/crypto/key-asymmetric/create.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/helpers/index.d.ts +2 -0
- package/dist/crypto/key-asymmetric/helpers/index.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/helpers/wrap.d.ts +5 -0
- package/dist/crypto/key-asymmetric/helpers/wrap.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/index.d.ts +8 -0
- package/dist/crypto/key-asymmetric/index.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/key-usages.d.ts +5 -0
- package/dist/crypto/key-asymmetric/key-usages.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/normalize.d.ts +4 -0
- package/dist/crypto/key-asymmetric/normalize.d.ts.map +1 -0
- package/dist/crypto/key-asymmetric/types.d.ts +30 -0
- package/dist/crypto/key-asymmetric/types.d.ts.map +1 -0
- package/dist/crypto/key-symmetric/check.d.ts +3 -0
- package/dist/crypto/key-symmetric/check.d.ts.map +1 -0
- package/dist/crypto/key-symmetric/constants.d.ts +7 -0
- package/dist/crypto/key-symmetric/constants.d.ts.map +1 -0
- package/dist/crypto/key-symmetric/create.d.ts +3 -0
- package/dist/crypto/key-symmetric/create.d.ts.map +1 -0
- package/dist/crypto/key-symmetric/index.d.ts +6 -0
- package/dist/crypto/key-symmetric/index.d.ts.map +1 -0
- package/dist/crypto/key-symmetric/key-usages.d.ts +2 -0
- package/dist/crypto/key-symmetric/key-usages.d.ts.map +1 -0
- package/dist/crypto/key-symmetric/normalize.d.ts +4 -0
- package/dist/crypto/key-symmetric/normalize.d.ts.map +1 -0
- package/dist/crypto/key-symmetric/types.d.ts +27 -0
- package/dist/crypto/key-symmetric/types.d.ts.map +1 -0
- package/dist/domain-event/module.d.ts +1 -1
- package/dist/domain-event/module.d.ts.map +1 -1
- package/dist/domain-event/type.d.ts +1 -1
- package/dist/domain-event/type.d.ts.map +1 -1
- package/dist/index.cjs +335 -296
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +304 -247
- package/dist/index.mjs.map +1 -1
- package/dist/services/cache/adapters/memory.d.ts +1 -0
- package/dist/services/cache/adapters/memory.d.ts.map +1 -1
- package/dist/services/cache/adapters/redis.d.ts +1 -0
- package/dist/services/cache/adapters/redis.d.ts.map +1 -1
- package/dist/services/cache/adapters/types.d.ts +1 -0
- package/dist/services/cache/adapters/types.d.ts.map +1 -1
- package/dist/services/logger/module.d.ts.map +1 -1
- package/package.json +15 -8
- package/dist/crypto/key-pair/constants.d.ts +0 -5
- package/dist/crypto/key-pair/constants.d.ts.map +0 -1
- package/dist/crypto/key-pair/create.d.ts +0 -3
- package/dist/crypto/key-pair/create.d.ts.map +0 -1
- package/dist/crypto/key-pair/delete.d.ts +0 -3
- package/dist/crypto/key-pair/delete.d.ts.map +0 -1
- package/dist/crypto/key-pair/helpers/check.d.ts +0 -4
- package/dist/crypto/key-pair/helpers/check.d.ts.map +0 -1
- package/dist/crypto/key-pair/helpers/file-name.d.ts +0 -4
- package/dist/crypto/key-pair/helpers/file-name.d.ts.map +0 -1
- package/dist/crypto/key-pair/helpers/index.d.ts +0 -6
- package/dist/crypto/key-pair/helpers/index.d.ts.map +0 -1
- package/dist/crypto/key-pair/helpers/options.d.ts +0 -3
- package/dist/crypto/key-pair/helpers/options.d.ts.map +0 -1
- package/dist/crypto/key-pair/helpers/private-key.d.ts +0 -3
- package/dist/crypto/key-pair/helpers/private-key.d.ts.map +0 -1
- package/dist/crypto/key-pair/helpers/wrap.d.ts +0 -5
- package/dist/crypto/key-pair/helpers/wrap.d.ts.map +0 -1
- package/dist/crypto/key-pair/index.d.ts +0 -9
- package/dist/crypto/key-pair/index.d.ts.map +0 -1
- package/dist/crypto/key-pair/load.d.ts +0 -3
- package/dist/crypto/key-pair/load.d.ts.map +0 -1
- package/dist/crypto/key-pair/module.d.ts +0 -3
- package/dist/crypto/key-pair/module.d.ts.map +0 -1
- package/dist/crypto/key-pair/save.d.ts +0 -3
- package/dist/crypto/key-pair/save.d.ts.map +0 -1
- package/dist/crypto/key-pair/type.d.ts +0 -64
- 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 {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
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
|
|
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
|
|
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
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
38
|
-
return
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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 (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
if (name === CryptoAsymmetricAlgorithm.ECDH) {
|
|
65
|
+
if (format === 'spki') {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
return [
|
|
69
|
+
'deriveKey',
|
|
70
|
+
'deriveBits'
|
|
71
|
+
];
|
|
64
72
|
}
|
|
65
|
-
if (
|
|
66
|
-
|
|
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
|
-
|
|
89
|
+
throw new SyntaxError(`Key usages can not be determined for asymmetric algorithm: ${name}`);
|
|
69
90
|
}
|
|
70
91
|
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
case
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
|
111
|
+
case CryptoAsymmetricAlgorithm.ECDSA:
|
|
112
|
+
case CryptoAsymmetricAlgorithm.ECDH:
|
|
93
113
|
{
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
144
|
+
return optionsNormalized;
|
|
111
145
|
}
|
|
112
146
|
|
|
113
|
-
function
|
|
114
|
-
const
|
|
115
|
-
|
|
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
|
|
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
|
|
142
|
-
return
|
|
160
|
+
function encodePKCS8ToPEM(base64) {
|
|
161
|
+
return enc('PRIVATE KEY', base64);
|
|
143
162
|
}
|
|
144
|
-
function
|
|
145
|
-
return
|
|
163
|
+
function encodeSPKIToPem(input) {
|
|
164
|
+
return enc('PUBLIC KEY', input);
|
|
146
165
|
}
|
|
147
166
|
// ------------------------------------------------------------
|
|
148
|
-
function
|
|
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
|
|
159
|
-
return
|
|
174
|
+
function decodePemToPKCS8(input) {
|
|
175
|
+
return dec('PRIVATE KEY', input);
|
|
160
176
|
}
|
|
161
|
-
function
|
|
162
|
-
return
|
|
177
|
+
function decodePemToSpki(input) {
|
|
178
|
+
return dec('PUBLIC KEY', input);
|
|
163
179
|
}
|
|
164
180
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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
|
-
|
|
212
|
-
|
|
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
|
-
|
|
235
|
+
throw new SyntaxError(`Key usages can not be determined for symmetric algorithm: ${name}`);
|
|
215
236
|
}
|
|
216
237
|
|
|
217
|
-
async function
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
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
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
privateKey = decryptRSAPrivateKey(options, privateKey);
|
|
264
|
+
async toUint8Array() {
|
|
265
|
+
const arrayBuffer = await this.toArrayBuffer();
|
|
266
|
+
return new Uint8Array(arrayBuffer);
|
|
247
267
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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 (
|
|
270
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
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
|
-
|
|
293
|
-
|
|
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
|
-
|
|
296
|
-
|
|
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
|
|
327
|
+
* @throws JWTError
|
|
309
328
|
*/ function extractTokenHeader(token) {
|
|
310
329
|
const parts = token.split('.');
|
|
311
330
|
if (parts.length !== 3) {
|
|
312
|
-
throw
|
|
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
|
|
350
|
+
throw JWTError.headerInvalid('The token header could not be extracted.');
|
|
332
351
|
}
|
|
333
352
|
}
|
|
334
|
-
|
|
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
|
|
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
|
|
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
|
|
372
|
+
if (isObject(e)) {
|
|
350
373
|
if (typeof e.name === 'string') {
|
|
351
374
|
switch(e.name){
|
|
352
375
|
case 'TokenExpiredError':
|
|
353
376
|
{
|
|
354
|
-
return
|
|
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
|
|
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
|
|
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
|
|
399
|
+
return JWTError.expired();
|
|
377
400
|
}
|
|
378
401
|
case 'ImmatureSignature':
|
|
379
402
|
{
|
|
380
|
-
return
|
|
403
|
+
return JWTError.notActiveBefore();
|
|
381
404
|
}
|
|
382
405
|
case 'InvalidToken':
|
|
383
406
|
case 'InvalidSignature':
|
|
384
407
|
{
|
|
385
|
-
return
|
|
408
|
+
return JWTError.payloadInvalid();
|
|
386
409
|
}
|
|
387
410
|
}
|
|
388
411
|
}
|
|
389
|
-
return new
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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, '
|
|
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,
|
|
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
|