@aura-stack/jose 0.1.0 → 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/index.cjs CHANGED
@@ -44,65 +44,155 @@ __export(index_exports, {
44
44
  });
45
45
  module.exports = __toCommonJS(index_exports);
46
46
 
47
- // src/encrypt.ts
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 Error("Secret is required");
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 Error("Secret string must be at least 32 characters long");
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/encrypt.ts
64
- var encryptJWE = async (payload, secret) => {
65
- const secretKey = createSecret(secret);
66
- const jti = import_node_crypto.default.randomBytes(32).toString("base64");
67
- return new import_jose.EncryptJWT({ token: payload }).setProtectedHeader({ alg: "dir", enc: "A256GCM", typ: "JWT", cty: "JWT" }).setIssuedAt().setNotBefore("0s").setExpirationTime("15d").setJti(jti).encrypt(secretKey);
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 decryptJWE = async (token, secret) => {
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.jwtDecrypt)(token, secretKey);
73
- return payload.token;
143
+ const { payload } = await (0, import_jose.jwtVerify)(token, secretKey, options);
144
+ return payload;
74
145
  } catch (error) {
75
- throw new Error("Invalid JWE", { cause: error });
146
+ if (isAuraJoseError(error)) {
147
+ throw error;
148
+ }
149
+ throw new JWSVerificationError("JWS signature verification failed", { cause: error });
76
150
  }
77
151
  };
78
- var createJWE = (secret) => {
152
+ var createJWS = (secret) => {
79
153
  return {
80
- encryptJWE: (payload) => encryptJWE(payload, secret),
81
- decryptJWE: (payload) => decryptJWE(payload, secret)
154
+ signJWS: (payload) => signJWS(payload, secret),
155
+ verifyJWS: (payload, options) => verifyJWS(payload, secret, options)
82
156
  };
83
157
  };
84
158
 
85
- // src/sign.ts
159
+ // src/encrypt.ts
86
160
  var import_node_crypto2 = __toESM(require("crypto"), 1);
87
161
  var import_jose2 = require("jose");
88
- var signJWS = async (payload, secret) => {
89
- const secretKey = createSecret(secret);
90
- const jti = import_node_crypto2.default.randomBytes(32).toString("base64");
91
- return new import_jose2.SignJWT(payload).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setNotBefore("0s").setExpirationTime("15d").setJti(jti).sign(secretKey);
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 verifyJWS = async (token, secret) => {
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.jwtVerify)(token, secretKey);
97
- return payload;
183
+ const { payload } = await (0, import_jose2.jwtDecrypt)(token, secretKey, options);
184
+ return payload.payload;
98
185
  } catch (error) {
99
- throw new Error("Invalid JWS", { cause: error });
186
+ if (isAuraJoseError(error)) {
187
+ throw error;
188
+ }
189
+ throw new JWEDecryptionError("JWE decryption verification failed", { cause: error });
100
190
  }
101
191
  };
102
- var createJWS = (secret) => {
192
+ var createJWE = (secret) => {
103
193
  return {
104
- signJWS: (payload) => signJWS(payload, secret),
105
- verifyJWS: (payload) => verifyJWS(payload, secret)
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 { signJWS: signJWS2 } = createJWS(secret);
132
- const { encryptJWE: encryptJWE2 } = createJWE(secret);
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
- throw new Error("Failed to encode JWT", { cause: error });
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 { verifyJWS: verifyJWS2 } = createJWS(secret);
142
- const { decryptJWE: decryptJWE2 } = createJWE(secret);
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
- throw new Error("Failed to decode JWT", { cause: error });
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
- token: string;
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-ODRHALUH.js";
4
+ } from "./chunk-K5BQTFSO.js";
5
5
  import {
6
6
  createJWE,
7
7
  decryptJWE,
8
8
  encryptJWE
9
- } from "./chunk-T7MMDRY3.js";
9
+ } from "./chunk-VPFE27PW.js";
10
10
  import {
11
11
  createJWS,
12
12
  signJWS,
13
13
  verifyJWS
14
- } from "./chunk-KSVD3YEC.js";
15
- import "./chunk-M4WAOCIJ.js";
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 { signJWS: signJWS2 } = createJWS(secret);
21
- const { encryptJWE: encryptJWE2 } = createJWE(secret);
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
- throw new Error("Failed to encode JWT", { cause: error });
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 { verifyJWS: verifyJWS2 } = createJWS(secret);
31
- const { decryptJWE: decryptJWE2 } = createJWE(secret);
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
- throw new Error("Failed to decode JWT", { cause: error });
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 Error("Secret is required");
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 Error("Secret string must be at least 32 characters long");
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
@@ -1,6 +1,10 @@
1
1
  import {
2
- createSecret
3
- } from "./chunk-M4WAOCIJ.js";
2
+ createSecret,
3
+ getSecrets
4
+ } from "./chunk-GXM4P5MQ.js";
5
+ import "./chunk-ZHFHDRQH.js";
6
+ import "./chunk-BMXFAB6Q.js";
4
7
  export {
5
- createSecret
8
+ createSecret,
9
+ getSecrets
6
10
  };
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 Error("Secret is required");
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 Error("Secret string must be at least 32 characters long");
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
- const secretKey = createSecret(secret);
56
- const jti = import_node_crypto.default.randomBytes(32).toString("base64");
57
- return new import_jose.SignJWT(payload).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuedAt().setNotBefore("0s").setExpirationTime("15d").setJti(jti).sign(secretKey);
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
- throw new Error("Invalid JWS", { cause: error });
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
@@ -1,3 +1,3 @@
1
- import 'jose';
1
+ export { JWTVerifyOptions } from 'jose';
2
2
  export { createJWS, signJWS, verifyJWS } from './index.js';
3
3
  import 'node:crypto';
package/dist/sign.js CHANGED
@@ -2,8 +2,10 @@ import {
2
2
  createJWS,
3
3
  signJWS,
4
4
  verifyJWS
5
- } from "./chunk-KSVD3YEC.js";
6
- import "./chunk-M4WAOCIJ.js";
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.1.0",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "JOSE utilities for @aura-stack/auth",
@@ -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
- };
@@ -1,15 +0,0 @@
1
- // src/secret.ts
2
- var createSecret = (secret) => {
3
- if (secret === void 0) throw new Error("Secret is required");
4
- if (typeof secret === "string") {
5
- if (new TextEncoder().encode(secret).byteLength < 32) {
6
- throw new Error("Secret string must be at least 32 characters long");
7
- }
8
- return new Uint8Array(Buffer.from(secret, "utf-8"));
9
- }
10
- return secret;
11
- };
12
-
13
- export {
14
- createSecret
15
- };