jsonauthtoken 3.0.3 → 3.0.4-beta-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node.index.d.mts +53 -0
- package/dist/node.index.d.ts +53 -0
- package/dist/node.index.js +767 -0
- package/dist/node.index.mjs +728 -0
- package/dist/types.d-D_Cze-FV.d.mts +32 -0
- package/dist/types.d-D_Cze-FV.d.ts +32 -0
- package/dist/types.d.ts +68 -0
- package/dist/web.index.d.mts +52 -0
- package/dist/web.index.d.ts +52 -0
- package/dist/web.index.js +599 -0
- package/dist/web.index.mjs +571 -0
- package/package.json +36 -5
- package/types.d.ts +54 -53
- package/dist/config/algo.config.d.ts +0 -2
- package/dist/config/algo.config.js +0 -28
- package/dist/config/name.config.d.ts +0 -1
- package/dist/config/name.config.js +0 -4
- package/dist/config/runtime.config.d.ts +0 -1
- package/dist/config/runtime.config.js +0 -15
- package/dist/index.d.ts +0 -34
- package/dist/index.js +0 -133
- package/dist/lib/decoading.lib.d.ts +0 -2
- package/dist/lib/decoading.lib.js +0 -9
- package/dist/lib/encoading.lib.d.ts +0 -2
- package/dist/lib/encoading.lib.js +0 -8
- package/dist/lib/functions.lib.d.ts +0 -12
- package/dist/lib/functions.lib.js +0 -85
- package/dist/lib/timeformat.d.ts +0 -1
- package/dist/lib/timeformat.js +0 -42
- package/dist/runtime/node.runtime.d.ts +0 -31
- package/dist/runtime/node.runtime.js +0 -146
- package/dist/runtime/runtime.d.ts +0 -12
- package/dist/runtime/runtime.js +0 -152
- package/dist/runtime/web.runtime.d.ts +0 -38
- package/dist/runtime/web.runtime.js +0 -180
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/web.index.ts
|
|
20
|
+
var web_index_exports = {};
|
|
21
|
+
__export(web_index_exports, {
|
|
22
|
+
JAT: () => JAT,
|
|
23
|
+
P2KG: () => P2KG,
|
|
24
|
+
default: () => web_index_default,
|
|
25
|
+
getSupportedAlgorithm: () => getSupportedAlgorithm
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(web_index_exports);
|
|
28
|
+
|
|
29
|
+
// src/config/name.config.ts
|
|
30
|
+
var RUNTIME = ["node", "web"];
|
|
31
|
+
var WEB_RUNTIME = ["web"];
|
|
32
|
+
|
|
33
|
+
// src/config/algo.config.ts
|
|
34
|
+
var SUPPORTED_ALGORITHM = {
|
|
35
|
+
node: [
|
|
36
|
+
{ name: "AES-256-GCM", value: "aes-256-gcm", type: "symmetric" },
|
|
37
|
+
{ name: "RSA+A256GCM", value: "rsa+a256gcm", type: "asymmetric" }
|
|
38
|
+
],
|
|
39
|
+
web: [
|
|
40
|
+
{ name: "AES-GCM", value: "AES-GCM", type: "symmetric" },
|
|
41
|
+
{ name: "RSA+AES-GCM", value: "RSA+AES-GCM", type: "asymmetric" }
|
|
42
|
+
]
|
|
43
|
+
};
|
|
44
|
+
function RUNTIME_DEFAULT_ALGORITHM(runtime) {
|
|
45
|
+
const algos = {
|
|
46
|
+
node: { name: "AES-256-GCM", value: "aes-256-gcm", type: "symmetric" },
|
|
47
|
+
web: { name: "AES-GCM", value: "AES-GCM", type: "symmetric" }
|
|
48
|
+
};
|
|
49
|
+
return algos[runtime];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/lib/encoading.lib.ts
|
|
53
|
+
function encoading(runtime, data) {
|
|
54
|
+
const json = JSON.stringify(data);
|
|
55
|
+
let base64;
|
|
56
|
+
if (runtime === "node") {
|
|
57
|
+
base64 = Buffer.from(json).toString("base64");
|
|
58
|
+
} else {
|
|
59
|
+
base64 = btoa(unescape(encodeURIComponent(json)));
|
|
60
|
+
}
|
|
61
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
62
|
+
}
|
|
63
|
+
var encoading_lib_default = encoading;
|
|
64
|
+
|
|
65
|
+
// src/lib/decoading.lib.ts
|
|
66
|
+
var decoading = (runtime, str) => {
|
|
67
|
+
const base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
68
|
+
const padding = "=".repeat((4 - base64.length % 4) % 4);
|
|
69
|
+
const base64WithPadding = base64 + padding;
|
|
70
|
+
let decoded;
|
|
71
|
+
if (runtime === "node") {
|
|
72
|
+
decoded = Buffer.from(base64WithPadding, "base64").toString("utf8");
|
|
73
|
+
} else {
|
|
74
|
+
decoded = decodeURIComponent(escape(atob(base64WithPadding)));
|
|
75
|
+
}
|
|
76
|
+
return JSON.parse(decoded);
|
|
77
|
+
};
|
|
78
|
+
var decoading_lib_default = decoading;
|
|
79
|
+
|
|
80
|
+
// src/lib/functions.lib.ts
|
|
81
|
+
function tokenFormatCreate(meta, encrypted) {
|
|
82
|
+
return `${encoading_lib_default(meta.runtime, meta)}:${encrypted}`;
|
|
83
|
+
}
|
|
84
|
+
function tokenFormatVerify(runtime, token) {
|
|
85
|
+
const index = token.indexOf(":");
|
|
86
|
+
if (index === -1) {
|
|
87
|
+
throw new Error("Invalid token format");
|
|
88
|
+
}
|
|
89
|
+
const metaPart = token.substring(0, index);
|
|
90
|
+
const encryptedPart = token.substring(index + 1);
|
|
91
|
+
const meta = decoading_lib_default(runtime, metaPart);
|
|
92
|
+
if (!meta) {
|
|
93
|
+
throw new Error("Invalid token format");
|
|
94
|
+
}
|
|
95
|
+
const algorithm = SUPPORTED_ALGORITHM[meta.runtime]?.find((e) => e.name === meta.algo);
|
|
96
|
+
if (!algorithm) {
|
|
97
|
+
throw new Error("Invalid token format");
|
|
98
|
+
}
|
|
99
|
+
if (algorithm.type !== meta.type) {
|
|
100
|
+
throw new Error("Invalid token format");
|
|
101
|
+
}
|
|
102
|
+
if (meta.type === "asymmetric") {
|
|
103
|
+
if (!meta.encryptedKey) {
|
|
104
|
+
throw new Error("Invalid token format");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!meta.iv) {
|
|
108
|
+
throw new Error("Invalid token format");
|
|
109
|
+
}
|
|
110
|
+
if (!RUNTIME.includes(meta.runtime)) {
|
|
111
|
+
throw new Error("Invalid token format");
|
|
112
|
+
}
|
|
113
|
+
if (meta.runtime === "node") {
|
|
114
|
+
if (!meta.tag) {
|
|
115
|
+
throw new Error("Invalid token format");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!meta.v) {
|
|
119
|
+
throw new Error("Invalid token format");
|
|
120
|
+
}
|
|
121
|
+
return { meta, encrypted: encryptedPart };
|
|
122
|
+
}
|
|
123
|
+
function isExpired(timeStamp) {
|
|
124
|
+
let currentTime = Math.floor(Date.now() / 1e3);
|
|
125
|
+
if (timeStamp < currentTime) {
|
|
126
|
+
return true;
|
|
127
|
+
} else {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function print({ dev = false, color = "green" }, ...args) {
|
|
132
|
+
if (!dev) return;
|
|
133
|
+
const colors = {
|
|
134
|
+
red: "\x1B[31m",
|
|
135
|
+
green: "\x1B[32m",
|
|
136
|
+
yellow: "\x1B[33m",
|
|
137
|
+
blue: "\x1B[34m",
|
|
138
|
+
magenta: "\x1B[35m",
|
|
139
|
+
cyan: "\x1B[36m",
|
|
140
|
+
white: "\x1B[37m",
|
|
141
|
+
reset: "\x1B[0m"
|
|
142
|
+
};
|
|
143
|
+
if (typeof window !== "undefined") {
|
|
144
|
+
console.log(`%c[jsonauthtoken]`, `color:${color}`, ...args);
|
|
145
|
+
} else {
|
|
146
|
+
const colorCode = colors[color] ?? colors.green;
|
|
147
|
+
console.log(`${colorCode}[jsonauthtoken]`, ...args, "\x1B[0m");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// src/lib/timeformat.ts
|
|
152
|
+
function jatTimeFormatter(input) {
|
|
153
|
+
if (typeof input === "number") {
|
|
154
|
+
if (input <= 0) {
|
|
155
|
+
throw new Error("Expiration time must be greater than zero.");
|
|
156
|
+
}
|
|
157
|
+
return Math.floor(Date.now() / 1e3) + input;
|
|
158
|
+
}
|
|
159
|
+
const regex = /^(\d+)(S|MIN|H|D|M|Y)$/i;
|
|
160
|
+
const match = input.match(regex);
|
|
161
|
+
if (!match) {
|
|
162
|
+
throw new Error("Invalid format. Use number or formats like 1S, 1MIN, 1H, 1D, 1M, or 1Y.");
|
|
163
|
+
}
|
|
164
|
+
const amount = parseInt(match[1], 10);
|
|
165
|
+
const unit = match[2].toUpperCase();
|
|
166
|
+
let seconds;
|
|
167
|
+
switch (unit) {
|
|
168
|
+
case "S":
|
|
169
|
+
seconds = amount;
|
|
170
|
+
break;
|
|
171
|
+
case "MIN":
|
|
172
|
+
seconds = amount * 60;
|
|
173
|
+
break;
|
|
174
|
+
case "H":
|
|
175
|
+
seconds = amount * 60 * 60;
|
|
176
|
+
break;
|
|
177
|
+
case "D":
|
|
178
|
+
seconds = amount * 24 * 60 * 60;
|
|
179
|
+
break;
|
|
180
|
+
case "M":
|
|
181
|
+
seconds = amount * 30 * 24 * 60 * 60;
|
|
182
|
+
break;
|
|
183
|
+
case "Y":
|
|
184
|
+
seconds = amount * 365 * 24 * 60 * 60;
|
|
185
|
+
break;
|
|
186
|
+
default:
|
|
187
|
+
throw new Error(`Unsupported time unit: ${unit}`);
|
|
188
|
+
}
|
|
189
|
+
return Math.floor(Date.now() / 1e3) + seconds;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/runtime/web.runtime.ts
|
|
193
|
+
var WebCrypto = class {
|
|
194
|
+
textEncoder = new TextEncoder();
|
|
195
|
+
textDecoder = new TextDecoder();
|
|
196
|
+
// Import AES key from password string
|
|
197
|
+
async __importAESKey(password) {
|
|
198
|
+
const passwordBuffer = this.textEncoder.encode(password);
|
|
199
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", passwordBuffer);
|
|
200
|
+
return await crypto.subtle.importKey(
|
|
201
|
+
"raw",
|
|
202
|
+
hashBuffer,
|
|
203
|
+
{ name: "AES-GCM" },
|
|
204
|
+
false,
|
|
205
|
+
["encrypt", "decrypt"]
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
//uint8Array to Base64
|
|
209
|
+
__uint8ArrayToBase64(uint8Array) {
|
|
210
|
+
let binary = "";
|
|
211
|
+
const len = uint8Array.byteLength;
|
|
212
|
+
for (let i = 0; i < len; i++) {
|
|
213
|
+
binary += String.fromCharCode(uint8Array[i]);
|
|
214
|
+
}
|
|
215
|
+
return btoa(binary);
|
|
216
|
+
}
|
|
217
|
+
//base64 to Uint8Array
|
|
218
|
+
__base64ToUint8Array(base64) {
|
|
219
|
+
const binaryString = atob(base64);
|
|
220
|
+
const len = binaryString.length;
|
|
221
|
+
const bytes = new Uint8Array(len);
|
|
222
|
+
for (let i = 0; i < len; i++) {
|
|
223
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
224
|
+
}
|
|
225
|
+
return bytes;
|
|
226
|
+
}
|
|
227
|
+
// ArrayBuffer to Base64
|
|
228
|
+
__arrayBufferToBase64(buffer) {
|
|
229
|
+
const bytes = new Uint8Array(buffer);
|
|
230
|
+
let binary = "";
|
|
231
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
232
|
+
binary += String.fromCharCode(bytes[i]);
|
|
233
|
+
}
|
|
234
|
+
return btoa(binary);
|
|
235
|
+
}
|
|
236
|
+
//Base64 to ArrayBuffer
|
|
237
|
+
__base64ToArrayBuffer(base64) {
|
|
238
|
+
const binary = atob(base64);
|
|
239
|
+
const bytes = new Uint8Array(binary.length);
|
|
240
|
+
for (let i = 0; i < binary.length; i++) {
|
|
241
|
+
bytes[i] = binary.charCodeAt(i);
|
|
242
|
+
}
|
|
243
|
+
return bytes.buffer;
|
|
244
|
+
}
|
|
245
|
+
//PEM to ArrayBuffer
|
|
246
|
+
__pemToArrayBuffer(pem, type) {
|
|
247
|
+
const pemHeader = `-----BEGIN ${type} KEY-----`;
|
|
248
|
+
const pemFooter = `-----END ${type} KEY-----`;
|
|
249
|
+
const pemContents = pem.replace(pemHeader, "").replace(pemFooter, "").replace(/\\n/g, "").replace(/\s/g, "");
|
|
250
|
+
return this.__base64ToArrayBuffer(pemContents);
|
|
251
|
+
}
|
|
252
|
+
//ArrayBuffer to PEM
|
|
253
|
+
__arrayBufferToPem(buffer, type) {
|
|
254
|
+
const base64 = this.__arrayBufferToBase64(buffer);
|
|
255
|
+
const pemContents = base64.match(/.{1,64}/g)?.join("\n") || base64;
|
|
256
|
+
return `-----BEGIN ${type} KEY-----
|
|
257
|
+
${pemContents}
|
|
258
|
+
-----END ${type} KEY-----`;
|
|
259
|
+
}
|
|
260
|
+
// Import RSA public key from PEM
|
|
261
|
+
async __importPublicKey(publicKeyPem) {
|
|
262
|
+
const keyData = this.__pemToArrayBuffer(publicKeyPem, "PUBLIC");
|
|
263
|
+
return await crypto.subtle.importKey(
|
|
264
|
+
"spki",
|
|
265
|
+
keyData,
|
|
266
|
+
{
|
|
267
|
+
name: "RSA-OAEP",
|
|
268
|
+
hash: "SHA-256"
|
|
269
|
+
},
|
|
270
|
+
true,
|
|
271
|
+
["encrypt"]
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
// Import RSA private key from PEM
|
|
275
|
+
async __importPrivateKey(privateKeyPem) {
|
|
276
|
+
const keyData = this.__pemToArrayBuffer(privateKeyPem.replace(/\\n/g, "\n"), "PRIVATE");
|
|
277
|
+
return await crypto.subtle.importKey(
|
|
278
|
+
"pkcs8",
|
|
279
|
+
keyData,
|
|
280
|
+
{
|
|
281
|
+
name: "RSA-OAEP",
|
|
282
|
+
hash: "SHA-256"
|
|
283
|
+
},
|
|
284
|
+
true,
|
|
285
|
+
["decrypt"]
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
// AES-256-GCM Encryption
|
|
289
|
+
async _encrypt(algo, key, payload) {
|
|
290
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
291
|
+
const data = this.textEncoder.encode(JSON.stringify(payload));
|
|
292
|
+
const encryptedBuffer = await crypto.subtle.encrypt(
|
|
293
|
+
{
|
|
294
|
+
name: algo,
|
|
295
|
+
iv,
|
|
296
|
+
tagLength: 128
|
|
297
|
+
},
|
|
298
|
+
key,
|
|
299
|
+
data
|
|
300
|
+
);
|
|
301
|
+
const encryptedBytes = new Uint8Array(encryptedBuffer);
|
|
302
|
+
return {
|
|
303
|
+
iv: this.__uint8ArrayToBase64(iv),
|
|
304
|
+
encrypted: this.__uint8ArrayToBase64(encryptedBytes)
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
// AES-256-GCM Decryption
|
|
308
|
+
async _decrypt(algo, key, encryptedData) {
|
|
309
|
+
const { iv, encrypted } = encryptedData;
|
|
310
|
+
const ivBuffer = this.__base64ToUint8Array(iv);
|
|
311
|
+
const encryptedBuffer = this.__base64ToUint8Array(encrypted);
|
|
312
|
+
try {
|
|
313
|
+
const decryptedBuffer = await crypto.subtle.decrypt(
|
|
314
|
+
{
|
|
315
|
+
name: algo,
|
|
316
|
+
iv: ivBuffer,
|
|
317
|
+
tagLength: 128
|
|
318
|
+
},
|
|
319
|
+
key,
|
|
320
|
+
encryptedBuffer
|
|
321
|
+
);
|
|
322
|
+
return JSON.parse(this.textDecoder.decode(decryptedBuffer));
|
|
323
|
+
} catch (error) {
|
|
324
|
+
throw new Error("Invalid Key");
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// Generate RSA public key from private key PEM
|
|
328
|
+
async _rsaPublicKeyGeneration(privateKeyPem) {
|
|
329
|
+
const privateKey = await this.__importPrivateKey(privateKeyPem);
|
|
330
|
+
const jwk = await crypto.subtle.exportKey("jwk", privateKey);
|
|
331
|
+
delete jwk.d;
|
|
332
|
+
delete jwk.dp;
|
|
333
|
+
delete jwk.dq;
|
|
334
|
+
delete jwk.q;
|
|
335
|
+
delete jwk.qi;
|
|
336
|
+
jwk.key_ops = ["encrypt"];
|
|
337
|
+
const publicKey = await crypto.subtle.importKey(
|
|
338
|
+
"jwk",
|
|
339
|
+
jwk,
|
|
340
|
+
{
|
|
341
|
+
name: "RSA-OAEP",
|
|
342
|
+
hash: "SHA-256"
|
|
343
|
+
},
|
|
344
|
+
true,
|
|
345
|
+
["encrypt"]
|
|
346
|
+
);
|
|
347
|
+
const exportedPublicKey = await crypto.subtle.exportKey("spki", publicKey);
|
|
348
|
+
return this.__arrayBufferToPem(exportedPublicKey, "PUBLIC");
|
|
349
|
+
}
|
|
350
|
+
async _rsaPrivatePublicKeyGeneration() {
|
|
351
|
+
const keyPair = await crypto.subtle.generateKey(
|
|
352
|
+
{
|
|
353
|
+
name: "RSA-OAEP",
|
|
354
|
+
modulusLength: 2048,
|
|
355
|
+
publicExponent: new Uint8Array([1, 0, 1]),
|
|
356
|
+
hash: "SHA-256"
|
|
357
|
+
},
|
|
358
|
+
true,
|
|
359
|
+
["encrypt", "decrypt"]
|
|
360
|
+
);
|
|
361
|
+
const privateKeyBuffer = await crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
|
|
362
|
+
const publicKeyBuffer = await crypto.subtle.exportKey("spki", keyPair.publicKey);
|
|
363
|
+
return {
|
|
364
|
+
privateKey: this.__arrayBufferToPem(privateKeyBuffer, "PRIVATE"),
|
|
365
|
+
publicKey: this.__arrayBufferToPem(publicKeyBuffer, "PUBLIC")
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
async encrypt(algo, key, payload, exp) {
|
|
369
|
+
const cryptoKey = await this.__importAESKey(key);
|
|
370
|
+
const newPayload = { payload, exp };
|
|
371
|
+
const { iv, encrypted } = await this._encrypt(algo, cryptoKey, newPayload);
|
|
372
|
+
return tokenFormatCreate(
|
|
373
|
+
{
|
|
374
|
+
runtime: "web",
|
|
375
|
+
algo: "AES-GCM",
|
|
376
|
+
type: "symmetric",
|
|
377
|
+
v: "1",
|
|
378
|
+
iv
|
|
379
|
+
},
|
|
380
|
+
encrypted
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
async decrypt(algo, key, encryptedData) {
|
|
384
|
+
const cryptoKey = await this.__importAESKey(key);
|
|
385
|
+
return await this._decrypt(algo, cryptoKey, encryptedData);
|
|
386
|
+
}
|
|
387
|
+
// Public method: Asymmetric encryption (RSA-OAEP + AES-256-GCM)
|
|
388
|
+
async encryptRSA(payload, publicKeyPem, exp) {
|
|
389
|
+
const symmetricKey = await crypto.subtle.generateKey(
|
|
390
|
+
{ name: "AES-GCM", length: 256 },
|
|
391
|
+
true,
|
|
392
|
+
["encrypt", "decrypt"]
|
|
393
|
+
);
|
|
394
|
+
const newPayload = { payload, exp };
|
|
395
|
+
const { iv, encrypted } = await this._encrypt("AES-GCM", symmetricKey, newPayload);
|
|
396
|
+
const symmetricKeyBuffer = await crypto.subtle.exportKey("raw", symmetricKey);
|
|
397
|
+
const publicKey = await this.__importPublicKey(publicKeyPem);
|
|
398
|
+
const encryptedSymmetricKey = await crypto.subtle.encrypt(
|
|
399
|
+
{
|
|
400
|
+
name: "RSA-OAEP"
|
|
401
|
+
},
|
|
402
|
+
publicKey,
|
|
403
|
+
symmetricKeyBuffer
|
|
404
|
+
);
|
|
405
|
+
return tokenFormatCreate(
|
|
406
|
+
{
|
|
407
|
+
runtime: "web",
|
|
408
|
+
algo: "RSA+AES-GCM",
|
|
409
|
+
type: "asymmetric",
|
|
410
|
+
v: "1",
|
|
411
|
+
iv,
|
|
412
|
+
encryptedKey: this.__arrayBufferToBase64(encryptedSymmetricKey)
|
|
413
|
+
},
|
|
414
|
+
encrypted
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
// Public method: Asymmetric decryption (RSA-OAEP + AES-256-GCM)
|
|
418
|
+
async decryptRSA(privateKeyPem, encryptedKey, encryptedData) {
|
|
419
|
+
const privateKey = await this.__importPrivateKey(privateKeyPem);
|
|
420
|
+
const encryptedKeyBuffer = this.__base64ToArrayBuffer(encryptedKey);
|
|
421
|
+
const decryptedSymmetricKeyBuffer = await crypto.subtle.decrypt(
|
|
422
|
+
{
|
|
423
|
+
name: "RSA-OAEP"
|
|
424
|
+
},
|
|
425
|
+
privateKey,
|
|
426
|
+
encryptedKeyBuffer
|
|
427
|
+
);
|
|
428
|
+
const symmetricKey = await crypto.subtle.importKey(
|
|
429
|
+
"raw",
|
|
430
|
+
decryptedSymmetricKeyBuffer,
|
|
431
|
+
{ name: "AES-GCM" },
|
|
432
|
+
false,
|
|
433
|
+
["decrypt"]
|
|
434
|
+
);
|
|
435
|
+
return await this._decrypt("AES-GCM", symmetricKey, encryptedData);
|
|
436
|
+
}
|
|
437
|
+
async rsaPrivatePublicKeyGeneration() {
|
|
438
|
+
return await this._rsaPrivatePublicKeyGeneration();
|
|
439
|
+
}
|
|
440
|
+
async rsaPublicKeyGeneration(privateKeyPem) {
|
|
441
|
+
return await this._rsaPublicKeyGeneration(privateKeyPem);
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
// src/web.index.ts
|
|
446
|
+
var WebCryptoModule = class {
|
|
447
|
+
dev = false;
|
|
448
|
+
runtime;
|
|
449
|
+
web = new WebCrypto();
|
|
450
|
+
constructor({ runtime, dev } = {}) {
|
|
451
|
+
try {
|
|
452
|
+
if (dev) this.dev = true;
|
|
453
|
+
if (runtime && !WEB_RUNTIME.includes(runtime)) {
|
|
454
|
+
throw new Error("Unsupported runtime");
|
|
455
|
+
}
|
|
456
|
+
this.runtime = "web";
|
|
457
|
+
print({ dev: this.dev }, "Current Runtime: ", this.runtime);
|
|
458
|
+
} catch (error) {
|
|
459
|
+
print({ dev: this.dev, color: "red" }, error);
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
async createToken(algo, key, payload, exp) {
|
|
464
|
+
const algorithms = SUPPORTED_ALGORITHM[this.runtime];
|
|
465
|
+
const algoData = algorithms.find(({ name }) => {
|
|
466
|
+
return name == algo;
|
|
467
|
+
});
|
|
468
|
+
if (!algoData) {
|
|
469
|
+
throw new Error(`Algorithm ${algo} is not supported for ${this.runtime}`);
|
|
470
|
+
}
|
|
471
|
+
if (algoData.type === "asymmetric") {
|
|
472
|
+
if (algoData.value !== "RSA+AES-GCM") {
|
|
473
|
+
throw new Error(`Algorithm ${algoData.name} is not supported for asymmetric encryption`);
|
|
474
|
+
}
|
|
475
|
+
return await this.web.encryptRSA(payload, key, exp);
|
|
476
|
+
} else {
|
|
477
|
+
if (algoData.value !== "AES-GCM") {
|
|
478
|
+
throw new Error(`Algorithm ${algoData.name} is not supported for symmetric encryption`);
|
|
479
|
+
}
|
|
480
|
+
return await this.web.encrypt(algoData.value, key, payload, exp);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
async verifyToken(token, key) {
|
|
484
|
+
const { meta, encrypted } = tokenFormatVerify(this.runtime, token);
|
|
485
|
+
const { runtime, algo, type, v, iv, tag, encryptedKey } = meta;
|
|
486
|
+
if (this.runtime !== runtime) {
|
|
487
|
+
throw new Error("Runtime not matching");
|
|
488
|
+
}
|
|
489
|
+
if (type === "asymmetric") {
|
|
490
|
+
if (algo !== "RSA+AES-GCM") {
|
|
491
|
+
throw new Error(`Algorithm ${algo} is not supported for asymmetric encryption`);
|
|
492
|
+
}
|
|
493
|
+
return await this.web.decryptRSA(key, encryptedKey, { iv, encrypted });
|
|
494
|
+
} else {
|
|
495
|
+
if (algo !== "AES-GCM") {
|
|
496
|
+
throw new Error(`Algorithm ${algo} is not supported for symmetric encryption`);
|
|
497
|
+
}
|
|
498
|
+
return await this.web.decrypt("AES-GCM", key, { iv, encrypted });
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
async create({ key, exp, algo }, payload) {
|
|
502
|
+
try {
|
|
503
|
+
if (!key) {
|
|
504
|
+
throw new Error("key is required to create token");
|
|
505
|
+
}
|
|
506
|
+
exp = exp ? jatTimeFormatter(exp) : jatTimeFormatter("5MIN");
|
|
507
|
+
algo = algo || RUNTIME_DEFAULT_ALGORITHM("web").name;
|
|
508
|
+
return await this.createToken(algo, key, payload, exp);
|
|
509
|
+
} catch (error) {
|
|
510
|
+
print({ dev: this.dev, color: "red" }, error);
|
|
511
|
+
throw error;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
async verify(token, key) {
|
|
515
|
+
try {
|
|
516
|
+
if (!token) {
|
|
517
|
+
throw new Error("Token is required to verify token");
|
|
518
|
+
}
|
|
519
|
+
if (!key) {
|
|
520
|
+
throw new Error("key is required to verify token");
|
|
521
|
+
}
|
|
522
|
+
const unfilterPayload = await this.verifyToken(token, key);
|
|
523
|
+
if (isExpired(unfilterPayload.exp)) {
|
|
524
|
+
throw new Error("Token expired");
|
|
525
|
+
}
|
|
526
|
+
return unfilterPayload.payload;
|
|
527
|
+
} catch (error) {
|
|
528
|
+
print({ dev: this.dev, color: "red" }, error);
|
|
529
|
+
throw error;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
var PrivatePublicKeyGeneration = class {
|
|
534
|
+
web = new WebCrypto();
|
|
535
|
+
async generateKeyPair(runtime, dev) {
|
|
536
|
+
let finalRuntime = "web";
|
|
537
|
+
const development = dev === true ? true : false;
|
|
538
|
+
try {
|
|
539
|
+
if (runtime) {
|
|
540
|
+
if (!WEB_RUNTIME.includes(runtime)) {
|
|
541
|
+
throw new Error("Unsupported runtime");
|
|
542
|
+
}
|
|
543
|
+
finalRuntime = runtime;
|
|
544
|
+
}
|
|
545
|
+
const { privateKey, publicKey } = await this.web.rsaPrivatePublicKeyGeneration();
|
|
546
|
+
print({ dev: development, color: "green" }, "Current Runtime: ", finalRuntime);
|
|
547
|
+
print({ dev: development, color: "green" }, { privateKey, publicKey });
|
|
548
|
+
return { privateKey, publicKey };
|
|
549
|
+
} catch (error) {
|
|
550
|
+
print({ dev: development, color: "red" }, error);
|
|
551
|
+
throw error;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
async generatePublicKey(privateKeyPem, runtime, dev) {
|
|
555
|
+
let finalRuntime = "web";
|
|
556
|
+
const development = dev === true ? true : false;
|
|
557
|
+
try {
|
|
558
|
+
if (runtime) {
|
|
559
|
+
if (!WEB_RUNTIME.includes(runtime)) {
|
|
560
|
+
throw new Error("Unsupported runtime");
|
|
561
|
+
}
|
|
562
|
+
finalRuntime = runtime;
|
|
563
|
+
}
|
|
564
|
+
const publicKey = await this.web.rsaPublicKeyGeneration(privateKeyPem);
|
|
565
|
+
print({ dev: development, color: "green" }, "Current Runtime: ", finalRuntime);
|
|
566
|
+
print({ dev: development, color: "green" }, publicKey);
|
|
567
|
+
return publicKey;
|
|
568
|
+
} catch (error) {
|
|
569
|
+
print({ dev: development, color: "red" }, error);
|
|
570
|
+
throw error;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
var p2kgObject = new PrivatePublicKeyGeneration();
|
|
575
|
+
var generateKeyPair = (options) => {
|
|
576
|
+
const { runtime, dev } = options || {};
|
|
577
|
+
return p2kgObject.generateKeyPair(runtime, dev);
|
|
578
|
+
};
|
|
579
|
+
var generatePublicKey = (privateKeyPem, options) => {
|
|
580
|
+
const { runtime, dev } = options || {};
|
|
581
|
+
return p2kgObject.generatePublicKey(privateKeyPem, runtime, dev);
|
|
582
|
+
};
|
|
583
|
+
var JAT = ({ runtime, dev } = {}) => new WebCryptoModule({ runtime, dev });
|
|
584
|
+
var getSupportedAlgorithm = () => SUPPORTED_ALGORITHM["web"];
|
|
585
|
+
var P2KG = {
|
|
586
|
+
generateKeyPair,
|
|
587
|
+
generatePublicKey
|
|
588
|
+
};
|
|
589
|
+
var jsonauthtoken = {
|
|
590
|
+
JAT,
|
|
591
|
+
P2KG
|
|
592
|
+
};
|
|
593
|
+
var web_index_default = jsonauthtoken;
|
|
594
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
595
|
+
0 && (module.exports = {
|
|
596
|
+
JAT,
|
|
597
|
+
P2KG,
|
|
598
|
+
getSupportedAlgorithm
|
|
599
|
+
});
|