@aura-stack/jose 0.1.0-rc.1 → 0.2.0
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/assert.cjs +69 -0
- package/dist/assert.d.ts +9 -0
- package/dist/assert.js +15 -0
- package/dist/chunk-BMXFAB6Q.js +47 -0
- package/dist/chunk-GXM4P5MQ.js +31 -0
- package/dist/{chunk-ODRHALUH.js → chunk-K5BQTFSO.js} +1 -1
- package/dist/chunk-VPFE27PW.js +58 -0
- package/dist/chunk-ZHDED44B.js +59 -0
- package/dist/chunk-ZHFHDRQH.js +29 -0
- package/dist/deriveKey.cjs +17 -2
- package/dist/deriveKey.js +4 -2
- package/dist/encrypt.cjs +60 -12
- package/dist/encrypt.d.ts +2 -2
- package/dist/encrypt.js +4 -2
- package/dist/errors.cjs +79 -0
- package/dist/errors.d.ts +34 -0
- package/dist/errors.js +22 -0
- package/dist/index.cjs +131 -33
- package/dist/index.d.ts +21 -12
- package/dist/index.js +27 -10
- package/dist/secret.cjs +36 -4
- package/dist/secret.d.ts +6 -2
- package/dist/secret.js +7 -3
- package/dist/sign.cjs +63 -9
- package/dist/sign.d.ts +1 -1
- package/dist/sign.js +4 -2
- package/package.json +6 -2
- package/dist/chunk-KSVD3YEC.js +0 -33
- package/dist/chunk-M4WAOCIJ.js +0 -15
- package/dist/chunk-T7MMDRY3.js +0 -33
package/dist/index.cjs
CHANGED
|
@@ -44,65 +44,155 @@ __export(index_exports, {
|
|
|
44
44
|
});
|
|
45
45
|
module.exports = __toCommonJS(index_exports);
|
|
46
46
|
|
|
47
|
-
// src/
|
|
47
|
+
// src/sign.ts
|
|
48
48
|
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
49
49
|
var import_jose = require("jose");
|
|
50
50
|
|
|
51
|
+
// src/errors.ts
|
|
52
|
+
var AuraJoseError = class extends Error {
|
|
53
|
+
static code = "ERR_AURA_JOSE_ERROR";
|
|
54
|
+
code;
|
|
55
|
+
constructor(message, options) {
|
|
56
|
+
super(message, options);
|
|
57
|
+
this.name = new.target.name;
|
|
58
|
+
this.code = new.target.code;
|
|
59
|
+
Error.captureStackTrace(this, new.target);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var JWTEncodingError = class extends AuraJoseError {
|
|
63
|
+
static code = "ERR_JWT_ENCODING";
|
|
64
|
+
};
|
|
65
|
+
var JWTDecodingError = class extends AuraJoseError {
|
|
66
|
+
static code = "ERR_JWT_DECODING";
|
|
67
|
+
};
|
|
68
|
+
var InvalidPayloadError = class extends AuraJoseError {
|
|
69
|
+
static code = "ERR_INVALID_PAYLOAD";
|
|
70
|
+
};
|
|
71
|
+
var JWSVerificationError = class extends AuraJoseError {
|
|
72
|
+
static code = "ERR_JWS_VERIFICATION";
|
|
73
|
+
};
|
|
74
|
+
var JWSSigningError = class extends AuraJoseError {
|
|
75
|
+
static code = "ERR_JWS_SIGNING";
|
|
76
|
+
};
|
|
77
|
+
var JWEDecryptionError = class extends AuraJoseError {
|
|
78
|
+
static code = "ERR_JWE_DECRYPTION";
|
|
79
|
+
};
|
|
80
|
+
var JWEEncryptionError = class extends AuraJoseError {
|
|
81
|
+
static code = "ERR_JWE_ENCRYPTION";
|
|
82
|
+
};
|
|
83
|
+
var InvalidSecretError = class extends AuraJoseError {
|
|
84
|
+
static code = "ERR_INVALID_SECRET";
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// src/assert.ts
|
|
88
|
+
var isAuraJoseError = (error) => {
|
|
89
|
+
return error instanceof AuraJoseError;
|
|
90
|
+
};
|
|
91
|
+
var isFalsy = (value) => {
|
|
92
|
+
return value === null || value === void 0 || value === false || value === 0 || value === "" || Number.isNaN(value);
|
|
93
|
+
};
|
|
94
|
+
var isObject = (value) => {
|
|
95
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
96
|
+
};
|
|
97
|
+
var isInvalidPayload = (payload) => {
|
|
98
|
+
return isFalsy(payload) || !isObject(payload) || typeof payload === "object" && payload !== null && !Array.isArray(payload) && Object.keys(payload).length === 0;
|
|
99
|
+
};
|
|
100
|
+
|
|
51
101
|
// src/secret.ts
|
|
52
102
|
var createSecret = (secret) => {
|
|
53
|
-
if (secret === void 0) throw new
|
|
103
|
+
if (secret === void 0) throw new InvalidSecretError("Secret is required");
|
|
54
104
|
if (typeof secret === "string") {
|
|
55
105
|
if (new TextEncoder().encode(secret).byteLength < 32) {
|
|
56
|
-
throw new
|
|
106
|
+
throw new InvalidSecretError("Secret string must be at least 32 characters long");
|
|
57
107
|
}
|
|
58
108
|
return new Uint8Array(Buffer.from(secret, "utf-8"));
|
|
59
109
|
}
|
|
60
110
|
return secret;
|
|
61
111
|
};
|
|
112
|
+
var getSecrets = (secret) => {
|
|
113
|
+
const jwsSecret = isObject(secret) && "jws" in secret ? secret.jws : secret;
|
|
114
|
+
const jweSecret = isObject(secret) && "jwe" in secret ? secret.jwe : secret;
|
|
115
|
+
return {
|
|
116
|
+
jwsSecret,
|
|
117
|
+
jweSecret
|
|
118
|
+
};
|
|
119
|
+
};
|
|
62
120
|
|
|
63
|
-
// src/
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
121
|
+
// src/sign.ts
|
|
122
|
+
var signJWS = async (payload, secret) => {
|
|
123
|
+
try {
|
|
124
|
+
if (isInvalidPayload(payload)) {
|
|
125
|
+
throw new InvalidPayloadError("The payload must be a non-empty object");
|
|
126
|
+
}
|
|
127
|
+
const secretKey = createSecret(secret);
|
|
128
|
+
const jti = import_node_crypto.default.randomBytes(32).toString("base64url");
|
|
129
|
+
return new import_jose.SignJWT(payload).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setNotBefore(payload.nbf ?? "0s").setExpirationTime(payload.exp ?? "15d").setJti(jti).sign(secretKey);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (isAuraJoseError(error)) {
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
throw new JWSSigningError("JWS signing failed", { cause: error });
|
|
135
|
+
}
|
|
68
136
|
};
|
|
69
|
-
var
|
|
137
|
+
var verifyJWS = async (token, secret, options) => {
|
|
70
138
|
try {
|
|
139
|
+
if (isFalsy(token)) {
|
|
140
|
+
throw new InvalidPayloadError("The token must be a non-empty string");
|
|
141
|
+
}
|
|
71
142
|
const secretKey = createSecret(secret);
|
|
72
|
-
const { payload } = await (0, import_jose.
|
|
73
|
-
return payload
|
|
143
|
+
const { payload } = await (0, import_jose.jwtVerify)(token, secretKey, options);
|
|
144
|
+
return payload;
|
|
74
145
|
} catch (error) {
|
|
75
|
-
|
|
146
|
+
if (isAuraJoseError(error)) {
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
throw new JWSVerificationError("JWS signature verification failed", { cause: error });
|
|
76
150
|
}
|
|
77
151
|
};
|
|
78
|
-
var
|
|
152
|
+
var createJWS = (secret) => {
|
|
79
153
|
return {
|
|
80
|
-
|
|
81
|
-
|
|
154
|
+
signJWS: (payload) => signJWS(payload, secret),
|
|
155
|
+
verifyJWS: (payload, options) => verifyJWS(payload, secret, options)
|
|
82
156
|
};
|
|
83
157
|
};
|
|
84
158
|
|
|
85
|
-
// src/
|
|
159
|
+
// src/encrypt.ts
|
|
86
160
|
var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
87
161
|
var import_jose2 = require("jose");
|
|
88
|
-
var
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
162
|
+
var encryptJWE = async (payload, secret, options) => {
|
|
163
|
+
try {
|
|
164
|
+
if (isFalsy(payload)) {
|
|
165
|
+
throw new InvalidPayloadError("The payload must be a non-empty string");
|
|
166
|
+
}
|
|
167
|
+
const secretKey = createSecret(secret);
|
|
168
|
+
const jti = import_node_crypto2.default.randomBytes(32).toString("base64url");
|
|
169
|
+
return new import_jose2.EncryptJWT({ payload }).setProtectedHeader({ alg: "dir", enc: "A256GCM", typ: "JWT", cty: "JWT" }).setIssuedAt().setNotBefore(options?.nbf ?? "0s").setExpirationTime(options?.exp ?? "15d").setJti(jti).encrypt(secretKey);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
if (isAuraJoseError(error)) {
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
throw new JWEEncryptionError("JWE encryption failed", { cause: error });
|
|
175
|
+
}
|
|
92
176
|
};
|
|
93
|
-
var
|
|
177
|
+
var decryptJWE = async (token, secret, options) => {
|
|
94
178
|
try {
|
|
179
|
+
if (isFalsy(token)) {
|
|
180
|
+
throw new InvalidPayloadError("The token must be a non-empty string");
|
|
181
|
+
}
|
|
95
182
|
const secretKey = createSecret(secret);
|
|
96
|
-
const { payload } = await (0, import_jose2.
|
|
97
|
-
return payload;
|
|
183
|
+
const { payload } = await (0, import_jose2.jwtDecrypt)(token, secretKey, options);
|
|
184
|
+
return payload.payload;
|
|
98
185
|
} catch (error) {
|
|
99
|
-
|
|
186
|
+
if (isAuraJoseError(error)) {
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
throw new JWEDecryptionError("JWE decryption verification failed", { cause: error });
|
|
100
190
|
}
|
|
101
191
|
};
|
|
102
|
-
var
|
|
192
|
+
var createJWE = (secret) => {
|
|
103
193
|
return {
|
|
104
|
-
|
|
105
|
-
|
|
194
|
+
encryptJWE: (payload, options) => encryptJWE(payload, secret, options),
|
|
195
|
+
decryptJWE: (payload, options) => decryptJWE(payload, secret, options)
|
|
106
196
|
};
|
|
107
197
|
};
|
|
108
198
|
|
|
@@ -128,22 +218,30 @@ var createDeriveKey = (secret, salt, info, length = 32) => {
|
|
|
128
218
|
// src/index.ts
|
|
129
219
|
var encodeJWT = async (token, secret) => {
|
|
130
220
|
try {
|
|
131
|
-
const {
|
|
132
|
-
const {
|
|
221
|
+
const { jweSecret, jwsSecret } = getSecrets(secret);
|
|
222
|
+
const { signJWS: signJWS2 } = createJWS(jwsSecret);
|
|
223
|
+
const { encryptJWE: encryptJWE2 } = createJWE(jweSecret);
|
|
133
224
|
const signed = await signJWS2(token);
|
|
134
225
|
return await encryptJWE2(signed);
|
|
135
226
|
} catch (error) {
|
|
136
|
-
|
|
227
|
+
if (isAuraJoseError(error)) {
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
throw new JWTEncodingError("JWT encoding failed", { cause: error });
|
|
137
231
|
}
|
|
138
232
|
};
|
|
139
233
|
var decodeJWT = async (token, secret) => {
|
|
140
234
|
try {
|
|
141
|
-
const {
|
|
142
|
-
const {
|
|
235
|
+
const { jweSecret, jwsSecret } = getSecrets(secret);
|
|
236
|
+
const { verifyJWS: verifyJWS2 } = createJWS(jwsSecret);
|
|
237
|
+
const { decryptJWE: decryptJWE2 } = createJWE(jweSecret);
|
|
143
238
|
const decrypted = await decryptJWE2(token);
|
|
144
239
|
return await verifyJWS2(decrypted);
|
|
145
240
|
} catch (error) {
|
|
146
|
-
|
|
241
|
+
if (isAuraJoseError(error)) {
|
|
242
|
+
throw error;
|
|
243
|
+
}
|
|
244
|
+
throw new JWTDecodingError("JWT decoding failed", { cause: error });
|
|
147
245
|
}
|
|
148
246
|
};
|
|
149
247
|
var createJWT = (secret) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { KeyObject, BinaryLike } from 'node:crypto';
|
|
2
|
-
import { JWTPayload } from 'jose';
|
|
2
|
+
import { JWTPayload, JWTVerifyOptions, JWTDecryptOptions } from 'jose';
|
|
3
|
+
export { JWTDecryptOptions, JWTVerifyOptions } from 'jose';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Sign a standard JWT token with the following claims:
|
|
@@ -24,7 +25,7 @@ declare const signJWS: (payload: JWTPayload, secret: SecretInput) => Promise<str
|
|
|
24
25
|
* @param secret - CryptoKey or KeyObject used to verify the JWT
|
|
25
26
|
* @returns verify and return the payload of the JWT
|
|
26
27
|
*/
|
|
27
|
-
declare const verifyJWS: (token: string, secret: SecretInput) => Promise<JWTPayload>;
|
|
28
|
+
declare const verifyJWS: (token: string, secret: SecretInput, options?: JWTVerifyOptions) => Promise<JWTPayload>;
|
|
28
29
|
/**
|
|
29
30
|
* Create a JWS (JSON Web Signature) signer and verifier. It implements the `signJWS`
|
|
30
31
|
* and `verifyJWS` functions of the module.
|
|
@@ -34,11 +35,15 @@ declare const verifyJWS: (token: string, secret: SecretInput) => Promise<JWTPayl
|
|
|
34
35
|
*/
|
|
35
36
|
declare const createJWS: (secret: SecretInput) => {
|
|
36
37
|
signJWS: (payload: JWTPayload) => Promise<string>;
|
|
37
|
-
verifyJWS: (payload: string) => Promise<JWTPayload>;
|
|
38
|
+
verifyJWS: (payload: string, options?: JWTVerifyOptions) => Promise<JWTPayload>;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
interface EncryptedPayload {
|
|
41
|
-
|
|
42
|
+
payload: string;
|
|
43
|
+
}
|
|
44
|
+
interface EncryptOptions {
|
|
45
|
+
nbf?: string | number | Date;
|
|
46
|
+
exp?: string | number | Date;
|
|
42
47
|
}
|
|
43
48
|
/**
|
|
44
49
|
* Encrypt a standard JWT token with the following claims:
|
|
@@ -51,7 +56,7 @@ interface EncryptedPayload {
|
|
|
51
56
|
* @param secret - Secret key to encrypt the JWT (CryptoKey, KeyObject, string or Uint8Array)
|
|
52
57
|
* @returns Encrypted JWT string
|
|
53
58
|
*/
|
|
54
|
-
declare const encryptJWE: (payload: string, secret: SecretInput) => Promise<string>;
|
|
59
|
+
declare const encryptJWE: (payload: string, secret: SecretInput, options?: EncryptOptions) => Promise<string>;
|
|
55
60
|
/**
|
|
56
61
|
* Decrypt a JWE token and return the payload if valid.
|
|
57
62
|
*
|
|
@@ -59,7 +64,7 @@ declare const encryptJWE: (payload: string, secret: SecretInput) => Promise<stri
|
|
|
59
64
|
* @param secret - Secret key to decrypt the JWT (CryptoKey, KeyObject, string or Uint8Array)
|
|
60
65
|
* @returns Decrypted JWT payload string
|
|
61
66
|
*/
|
|
62
|
-
declare const decryptJWE: (token: string, secret: SecretInput) => Promise<string>;
|
|
67
|
+
declare const decryptJWE: (token: string, secret: SecretInput, options?: JWTDecryptOptions) => Promise<string>;
|
|
63
68
|
/**
|
|
64
69
|
* Creates a `JWE (JSON Web Encryption)` encrypter and decrypter. It implements the `encryptJWE`
|
|
65
70
|
* and `decryptJWE` functions of the module.
|
|
@@ -68,8 +73,8 @@ declare const decryptJWE: (token: string, secret: SecretInput) => Promise<string
|
|
|
68
73
|
* @returns encryptJWE and decryptJWE functions
|
|
69
74
|
*/
|
|
70
75
|
declare const createJWE: (secret: SecretInput) => {
|
|
71
|
-
encryptJWE: (payload: string) => Promise<string>;
|
|
72
|
-
decryptJWE: (payload: string) => Promise<string>;
|
|
76
|
+
encryptJWE: (payload: string, options?: EncryptOptions) => Promise<string>;
|
|
77
|
+
decryptJWE: (payload: string, options?: JWTDecryptOptions) => Promise<string>;
|
|
73
78
|
};
|
|
74
79
|
|
|
75
80
|
/**
|
|
@@ -77,6 +82,10 @@ declare const createJWE: (secret: SecretInput) => {
|
|
|
77
82
|
*/
|
|
78
83
|
|
|
79
84
|
type SecretInput = KeyObject | Uint8Array | string;
|
|
85
|
+
type DerivedKeyInput = {
|
|
86
|
+
jws: SecretInput;
|
|
87
|
+
jwe: SecretInput;
|
|
88
|
+
};
|
|
80
89
|
/**
|
|
81
90
|
* Encode a JWT signed and encrypted token. The token first signed using JWS
|
|
82
91
|
* and then encrypted using JWE to ensure both integrity and confidentiality.
|
|
@@ -91,7 +100,7 @@ type SecretInput = KeyObject | Uint8Array | string;
|
|
|
91
100
|
* @param secret - Secret key used for both signing and encrypting the JWT
|
|
92
101
|
* @returns Promise resolving to the signed and encrypted JWT string
|
|
93
102
|
*/
|
|
94
|
-
declare const encodeJWT: (token: JWTPayload, secret: SecretInput) => Promise<string>;
|
|
103
|
+
declare const encodeJWT: (token: JWTPayload, secret: SecretInput | DerivedKeyInput) => Promise<string>;
|
|
95
104
|
/**
|
|
96
105
|
* Decode a JWT signed and encrypted token. The token is first decrypted using JWE
|
|
97
106
|
* and then verified using JWS to ensure both confidentiality and integrity. It
|
|
@@ -104,7 +113,7 @@ declare const encodeJWT: (token: JWTPayload, secret: SecretInput) => Promise<str
|
|
|
104
113
|
* @param secret
|
|
105
114
|
* @returns
|
|
106
115
|
*/
|
|
107
|
-
declare const decodeJWT: (token: string, secret: SecretInput) => Promise<JWTPayload>;
|
|
116
|
+
declare const decodeJWT: (token: string, secret: SecretInput | DerivedKeyInput) => Promise<JWTPayload>;
|
|
108
117
|
/**
|
|
109
118
|
* Create a JWT handler with encode and decode methods to `signJWS/encryptJWE` and `verifyJWS/decryptJWE`
|
|
110
119
|
* JWT tokens. The JWTs are signed and verified using JWS and encrypted and decrypted using JWE. It
|
|
@@ -113,7 +122,7 @@ declare const decodeJWT: (token: string, secret: SecretInput) => Promise<JWTPayl
|
|
|
113
122
|
* @param secret - Secret key used for signing, verifying, encrypting and decrypting the JWT
|
|
114
123
|
* @returns JWT handler object with `signJWS/encryptJWE` and `verifyJWS/decryptJWE` methods
|
|
115
124
|
*/
|
|
116
|
-
declare const createJWT: (secret: SecretInput) => {
|
|
125
|
+
declare const createJWT: (secret: SecretInput | DerivedKeyInput) => {
|
|
117
126
|
encodeJWT: (payload: JWTPayload) => Promise<string>;
|
|
118
127
|
decodeJWT: (token: string) => Promise<JWTPayload>;
|
|
119
128
|
};
|
|
@@ -142,4 +151,4 @@ declare const createDeriveKey: (secret: SecretInput, salt?: BinaryLike, info?: s
|
|
|
142
151
|
derivedKey: Buffer<ArrayBuffer>;
|
|
143
152
|
};
|
|
144
153
|
|
|
145
|
-
export { type EncryptedPayload, type SecretInput, createDeriveKey, createJWE, createJWS, createJWT, decodeJWT, decryptJWE, deriveKey, encodeJWT, encryptJWE, signJWS, verifyJWS };
|
|
154
|
+
export { type DerivedKeyInput, type EncryptOptions, type EncryptedPayload, type SecretInput, createDeriveKey, createJWE, createJWS, createJWT, decodeJWT, decryptJWE, deriveKey, encodeJWT, encryptJWE, signJWS, verifyJWS };
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,55 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createDeriveKey,
|
|
3
3
|
deriveKey
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-K5BQTFSO.js";
|
|
5
5
|
import {
|
|
6
6
|
createJWE,
|
|
7
7
|
decryptJWE,
|
|
8
8
|
encryptJWE
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VPFE27PW.js";
|
|
10
10
|
import {
|
|
11
11
|
createJWS,
|
|
12
12
|
signJWS,
|
|
13
13
|
verifyJWS
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import
|
|
14
|
+
} from "./chunk-ZHDED44B.js";
|
|
15
|
+
import {
|
|
16
|
+
getSecrets
|
|
17
|
+
} from "./chunk-GXM4P5MQ.js";
|
|
18
|
+
import {
|
|
19
|
+
isAuraJoseError
|
|
20
|
+
} from "./chunk-ZHFHDRQH.js";
|
|
21
|
+
import {
|
|
22
|
+
JWTDecodingError,
|
|
23
|
+
JWTEncodingError
|
|
24
|
+
} from "./chunk-BMXFAB6Q.js";
|
|
16
25
|
|
|
17
26
|
// src/index.ts
|
|
18
27
|
var encodeJWT = async (token, secret) => {
|
|
19
28
|
try {
|
|
20
|
-
const {
|
|
21
|
-
const {
|
|
29
|
+
const { jweSecret, jwsSecret } = getSecrets(secret);
|
|
30
|
+
const { signJWS: signJWS2 } = createJWS(jwsSecret);
|
|
31
|
+
const { encryptJWE: encryptJWE2 } = createJWE(jweSecret);
|
|
22
32
|
const signed = await signJWS2(token);
|
|
23
33
|
return await encryptJWE2(signed);
|
|
24
34
|
} catch (error) {
|
|
25
|
-
|
|
35
|
+
if (isAuraJoseError(error)) {
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
throw new JWTEncodingError("JWT encoding failed", { cause: error });
|
|
26
39
|
}
|
|
27
40
|
};
|
|
28
41
|
var decodeJWT = async (token, secret) => {
|
|
29
42
|
try {
|
|
30
|
-
const {
|
|
31
|
-
const {
|
|
43
|
+
const { jweSecret, jwsSecret } = getSecrets(secret);
|
|
44
|
+
const { verifyJWS: verifyJWS2 } = createJWS(jwsSecret);
|
|
45
|
+
const { decryptJWE: decryptJWE2 } = createJWE(jweSecret);
|
|
32
46
|
const decrypted = await decryptJWE2(token);
|
|
33
47
|
return await verifyJWS2(decrypted);
|
|
34
48
|
} catch (error) {
|
|
35
|
-
|
|
49
|
+
if (isAuraJoseError(error)) {
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
throw new JWTDecodingError("JWT decoding failed", { cause: error });
|
|
36
53
|
}
|
|
37
54
|
};
|
|
38
55
|
var createJWT = (secret) => {
|
package/dist/secret.cjs
CHANGED
|
@@ -20,20 +20,52 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/secret.ts
|
|
21
21
|
var secret_exports = {};
|
|
22
22
|
__export(secret_exports, {
|
|
23
|
-
createSecret: () => createSecret
|
|
23
|
+
createSecret: () => createSecret,
|
|
24
|
+
getSecrets: () => getSecrets
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(secret_exports);
|
|
27
|
+
|
|
28
|
+
// src/errors.ts
|
|
29
|
+
var AuraJoseError = class extends Error {
|
|
30
|
+
static code = "ERR_AURA_JOSE_ERROR";
|
|
31
|
+
code;
|
|
32
|
+
constructor(message, options) {
|
|
33
|
+
super(message, options);
|
|
34
|
+
this.name = new.target.name;
|
|
35
|
+
this.code = new.target.code;
|
|
36
|
+
Error.captureStackTrace(this, new.target);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var InvalidSecretError = class extends AuraJoseError {
|
|
40
|
+
static code = "ERR_INVALID_SECRET";
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/assert.ts
|
|
44
|
+
var isObject = (value) => {
|
|
45
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// src/secret.ts
|
|
26
49
|
var createSecret = (secret) => {
|
|
27
|
-
if (secret === void 0) throw new
|
|
50
|
+
if (secret === void 0) throw new InvalidSecretError("Secret is required");
|
|
28
51
|
if (typeof secret === "string") {
|
|
29
52
|
if (new TextEncoder().encode(secret).byteLength < 32) {
|
|
30
|
-
throw new
|
|
53
|
+
throw new InvalidSecretError("Secret string must be at least 32 characters long");
|
|
31
54
|
}
|
|
32
55
|
return new Uint8Array(Buffer.from(secret, "utf-8"));
|
|
33
56
|
}
|
|
34
57
|
return secret;
|
|
35
58
|
};
|
|
59
|
+
var getSecrets = (secret) => {
|
|
60
|
+
const jwsSecret = isObject(secret) && "jws" in secret ? secret.jws : secret;
|
|
61
|
+
const jweSecret = isObject(secret) && "jwe" in secret ? secret.jwe : secret;
|
|
62
|
+
return {
|
|
63
|
+
jwsSecret,
|
|
64
|
+
jweSecret
|
|
65
|
+
};
|
|
66
|
+
};
|
|
36
67
|
// Annotate the CommonJS export names for ESM import in node:
|
|
37
68
|
0 && (module.exports = {
|
|
38
|
-
createSecret
|
|
69
|
+
createSecret,
|
|
70
|
+
getSecrets
|
|
39
71
|
});
|
package/dist/secret.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as crypto from 'crypto';
|
|
2
|
-
import { SecretInput } from './index.js';
|
|
2
|
+
import { SecretInput, DerivedKeyInput } from './index.js';
|
|
3
3
|
import 'node:crypto';
|
|
4
4
|
import 'jose';
|
|
5
5
|
|
|
@@ -10,5 +10,9 @@ import 'jose';
|
|
|
10
10
|
* @returns The secret in Uint8Array format
|
|
11
11
|
*/
|
|
12
12
|
declare const createSecret: (secret: SecretInput) => crypto.KeyObject | Uint8Array<ArrayBufferLike>;
|
|
13
|
+
declare const getSecrets: (secret: SecretInput | DerivedKeyInput) => {
|
|
14
|
+
jwsSecret: SecretInput;
|
|
15
|
+
jweSecret: SecretInput;
|
|
16
|
+
};
|
|
13
17
|
|
|
14
|
-
export { createSecret };
|
|
18
|
+
export { createSecret, getSecrets };
|
package/dist/secret.js
CHANGED
package/dist/sign.cjs
CHANGED
|
@@ -38,12 +38,50 @@ module.exports = __toCommonJS(sign_exports);
|
|
|
38
38
|
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
39
39
|
var import_jose = require("jose");
|
|
40
40
|
|
|
41
|
+
// src/errors.ts
|
|
42
|
+
var AuraJoseError = class extends Error {
|
|
43
|
+
static code = "ERR_AURA_JOSE_ERROR";
|
|
44
|
+
code;
|
|
45
|
+
constructor(message, options) {
|
|
46
|
+
super(message, options);
|
|
47
|
+
this.name = new.target.name;
|
|
48
|
+
this.code = new.target.code;
|
|
49
|
+
Error.captureStackTrace(this, new.target);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var InvalidPayloadError = class extends AuraJoseError {
|
|
53
|
+
static code = "ERR_INVALID_PAYLOAD";
|
|
54
|
+
};
|
|
55
|
+
var JWSVerificationError = class extends AuraJoseError {
|
|
56
|
+
static code = "ERR_JWS_VERIFICATION";
|
|
57
|
+
};
|
|
58
|
+
var JWSSigningError = class extends AuraJoseError {
|
|
59
|
+
static code = "ERR_JWS_SIGNING";
|
|
60
|
+
};
|
|
61
|
+
var InvalidSecretError = class extends AuraJoseError {
|
|
62
|
+
static code = "ERR_INVALID_SECRET";
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/assert.ts
|
|
66
|
+
var isAuraJoseError = (error) => {
|
|
67
|
+
return error instanceof AuraJoseError;
|
|
68
|
+
};
|
|
69
|
+
var isFalsy = (value) => {
|
|
70
|
+
return value === null || value === void 0 || value === false || value === 0 || value === "" || Number.isNaN(value);
|
|
71
|
+
};
|
|
72
|
+
var isObject = (value) => {
|
|
73
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
74
|
+
};
|
|
75
|
+
var isInvalidPayload = (payload) => {
|
|
76
|
+
return isFalsy(payload) || !isObject(payload) || typeof payload === "object" && payload !== null && !Array.isArray(payload) && Object.keys(payload).length === 0;
|
|
77
|
+
};
|
|
78
|
+
|
|
41
79
|
// src/secret.ts
|
|
42
80
|
var createSecret = (secret) => {
|
|
43
|
-
if (secret === void 0) throw new
|
|
81
|
+
if (secret === void 0) throw new InvalidSecretError("Secret is required");
|
|
44
82
|
if (typeof secret === "string") {
|
|
45
83
|
if (new TextEncoder().encode(secret).byteLength < 32) {
|
|
46
|
-
throw new
|
|
84
|
+
throw new InvalidSecretError("Secret string must be at least 32 characters long");
|
|
47
85
|
}
|
|
48
86
|
return new Uint8Array(Buffer.from(secret, "utf-8"));
|
|
49
87
|
}
|
|
@@ -52,23 +90,39 @@ var createSecret = (secret) => {
|
|
|
52
90
|
|
|
53
91
|
// src/sign.ts
|
|
54
92
|
var signJWS = async (payload, secret) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
93
|
+
try {
|
|
94
|
+
if (isInvalidPayload(payload)) {
|
|
95
|
+
throw new InvalidPayloadError("The payload must be a non-empty object");
|
|
96
|
+
}
|
|
97
|
+
const secretKey = createSecret(secret);
|
|
98
|
+
const jti = import_node_crypto.default.randomBytes(32).toString("base64url");
|
|
99
|
+
return new import_jose.SignJWT(payload).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setNotBefore(payload.nbf ?? "0s").setExpirationTime(payload.exp ?? "15d").setJti(jti).sign(secretKey);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (isAuraJoseError(error)) {
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
throw new JWSSigningError("JWS signing failed", { cause: error });
|
|
105
|
+
}
|
|
58
106
|
};
|
|
59
|
-
var verifyJWS = async (token, secret) => {
|
|
107
|
+
var verifyJWS = async (token, secret, options) => {
|
|
60
108
|
try {
|
|
109
|
+
if (isFalsy(token)) {
|
|
110
|
+
throw new InvalidPayloadError("The token must be a non-empty string");
|
|
111
|
+
}
|
|
61
112
|
const secretKey = createSecret(secret);
|
|
62
|
-
const { payload } = await (0, import_jose.jwtVerify)(token, secretKey);
|
|
113
|
+
const { payload } = await (0, import_jose.jwtVerify)(token, secretKey, options);
|
|
63
114
|
return payload;
|
|
64
115
|
} catch (error) {
|
|
65
|
-
|
|
116
|
+
if (isAuraJoseError(error)) {
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
throw new JWSVerificationError("JWS signature verification failed", { cause: error });
|
|
66
120
|
}
|
|
67
121
|
};
|
|
68
122
|
var createJWS = (secret) => {
|
|
69
123
|
return {
|
|
70
124
|
signJWS: (payload) => signJWS(payload, secret),
|
|
71
|
-
verifyJWS: (payload) => verifyJWS(payload, secret)
|
|
125
|
+
verifyJWS: (payload, options) => verifyJWS(payload, secret, options)
|
|
72
126
|
};
|
|
73
127
|
};
|
|
74
128
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/sign.d.ts
CHANGED
package/dist/sign.js
CHANGED
|
@@ -2,8 +2,10 @@ import {
|
|
|
2
2
|
createJWS,
|
|
3
3
|
signJWS,
|
|
4
4
|
verifyJWS
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-ZHDED44B.js";
|
|
6
|
+
import "./chunk-GXM4P5MQ.js";
|
|
7
|
+
import "./chunk-ZHFHDRQH.js";
|
|
8
|
+
import "./chunk-BMXFAB6Q.js";
|
|
7
9
|
export {
|
|
8
10
|
createJWS,
|
|
9
11
|
signJWS,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aura-stack/jose",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "JOSE utilities for @aura-stack/auth",
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/aura-stack-ts/auth"
|
|
10
10
|
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public",
|
|
13
|
+
"registry": "https://registry.npmjs.org/@aura-stack/jose"
|
|
14
|
+
},
|
|
11
15
|
"files": [
|
|
12
16
|
"dist"
|
|
13
17
|
],
|
|
@@ -66,7 +70,7 @@
|
|
|
66
70
|
"format:check": "prettier --check . --cache --cache-location .cache/.prettiercache",
|
|
67
71
|
"type-check": "tsc --noEmit",
|
|
68
72
|
"clean": "rm -rf dist",
|
|
69
|
-
"clean:cts": "
|
|
73
|
+
"clean:cts": "find dist -type f -name \"*.cts\" -delete",
|
|
70
74
|
"prepublish": "pnpm clean:cts"
|
|
71
75
|
}
|
|
72
76
|
}
|
package/dist/chunk-KSVD3YEC.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createSecret
|
|
3
|
-
} from "./chunk-M4WAOCIJ.js";
|
|
4
|
-
|
|
5
|
-
// src/sign.ts
|
|
6
|
-
import crypto from "crypto";
|
|
7
|
-
import { jwtVerify, SignJWT } from "jose";
|
|
8
|
-
var signJWS = async (payload, secret) => {
|
|
9
|
-
const secretKey = createSecret(secret);
|
|
10
|
-
const jti = crypto.randomBytes(32).toString("base64");
|
|
11
|
-
return new SignJWT(payload).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setNotBefore("0s").setExpirationTime("15d").setJti(jti).sign(secretKey);
|
|
12
|
-
};
|
|
13
|
-
var verifyJWS = async (token, secret) => {
|
|
14
|
-
try {
|
|
15
|
-
const secretKey = createSecret(secret);
|
|
16
|
-
const { payload } = await jwtVerify(token, secretKey);
|
|
17
|
-
return payload;
|
|
18
|
-
} catch (error) {
|
|
19
|
-
throw new Error("Invalid JWS", { cause: error });
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
var createJWS = (secret) => {
|
|
23
|
-
return {
|
|
24
|
-
signJWS: (payload) => signJWS(payload, secret),
|
|
25
|
-
verifyJWS: (payload) => verifyJWS(payload, secret)
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export {
|
|
30
|
-
signJWS,
|
|
31
|
-
verifyJWS,
|
|
32
|
-
createJWS
|
|
33
|
-
};
|