@lindorm/aegis 0.3.5 → 0.4.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/CHANGELOG.md +25 -0
- package/README.md +247 -163
- package/__tests__/__mocks__/cbor.ts +17 -0
- package/__tests__/cose-interop.test.ts +1127 -0
- package/__tests__/jwe-interop.test.ts +331 -0
- package/__tests__/jwt-interop.test.ts +183 -0
- package/dist/classes/Aegis.d.ts.map +1 -1
- package/dist/classes/Aegis.js +8 -5
- package/dist/classes/Aegis.js.map +1 -1
- package/dist/classes/CweKit.d.ts.map +1 -1
- package/dist/classes/CweKit.js +31 -37
- package/dist/classes/CweKit.js.map +1 -1
- package/dist/classes/CwsKit.d.ts.map +1 -1
- package/dist/classes/CwsKit.js +8 -3
- package/dist/classes/CwsKit.js.map +1 -1
- package/dist/classes/CwtKit.d.ts.map +1 -1
- package/dist/classes/CwtKit.js +10 -14
- package/dist/classes/CwtKit.js.map +1 -1
- package/dist/classes/JweKit.d.ts.map +1 -1
- package/dist/classes/JweKit.js +24 -47
- package/dist/classes/JweKit.js.map +1 -1
- package/dist/classes/JwsKit.d.ts.map +1 -1
- package/dist/classes/JwsKit.js +9 -2
- package/dist/classes/JwsKit.js.map +1 -1
- package/dist/classes/JwtKit.d.ts.map +1 -1
- package/dist/classes/JwtKit.js +10 -9
- package/dist/classes/JwtKit.js.map +1 -1
- package/dist/classes/SignatureKit.d.ts.map +1 -1
- package/dist/classes/SignatureKit.js +2 -1
- package/dist/classes/SignatureKit.js.map +1 -1
- package/dist/constants/private/cose.d.ts +0 -1
- package/dist/constants/private/cose.d.ts.map +1 -1
- package/dist/constants/private/cose.js +5 -23
- package/dist/constants/private/cose.js.map +1 -1
- package/dist/types/cose-target.d.ts +2 -0
- package/dist/types/cose-target.d.ts.map +1 -0
- package/dist/types/{operators.js → cose-target.js} +1 -1
- package/dist/types/cose-target.js.map +1 -0
- package/dist/types/cwe/cwe-decode.d.ts +6 -2
- package/dist/types/cwe/cwe-decode.d.ts.map +1 -1
- package/dist/types/cwe/cwe-decrypt.d.ts +2 -2
- package/dist/types/cwe/cwe-decrypt.d.ts.map +1 -1
- package/dist/types/cwe/cwe-encrypt.d.ts +2 -0
- package/dist/types/cwe/cwe-encrypt.d.ts.map +1 -1
- package/dist/types/cws/cws-sign.d.ts +2 -0
- package/dist/types/cws/cws-sign.d.ts.map +1 -1
- package/dist/types/cwt/cwt-sign.d.ts +4 -1
- package/dist/types/cwt/cwt-sign.d.ts.map +1 -1
- package/dist/types/header.d.ts +6 -10
- package/dist/types/header.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/jwt/jwt-validate.d.ts +21 -21
- package/dist/types/jwt/jwt-validate.d.ts.map +1 -1
- package/dist/types/jwt/jwt-verify.d.ts +21 -21
- package/dist/types/jwt/jwt-verify.d.ts.map +1 -1
- package/dist/utils/private/auth-tag-length.js.map +1 -1
- package/dist/utils/private/cose/claims.d.ts +3 -3
- package/dist/utils/private/cose/claims.d.ts.map +1 -1
- package/dist/utils/private/cose/claims.js +27 -5
- package/dist/utils/private/cose/claims.js.map +1 -1
- package/dist/utils/private/cose/header.d.ts +3 -3
- package/dist/utils/private/cose/header.d.ts.map +1 -1
- package/dist/utils/private/cose/header.js +19 -26
- package/dist/utils/private/cose/header.js.map +1 -1
- package/dist/utils/private/cose/key.d.ts +1 -1
- package/dist/utils/private/cose/key.d.ts.map +1 -1
- package/dist/utils/private/cose/key.js +16 -12
- package/dist/utils/private/cose/key.js.map +1 -1
- package/dist/utils/private/cose-sign-token.d.ts +1 -2
- package/dist/utils/private/cose-sign-token.d.ts.map +1 -1
- package/dist/utils/private/cose-sign-token.js.map +1 -1
- package/dist/utils/private/index.d.ts +0 -1
- package/dist/utils/private/index.d.ts.map +1 -1
- package/dist/utils/private/index.js +0 -1
- package/dist/utils/private/index.js.map +1 -1
- package/dist/utils/private/jose-header.d.ts.map +1 -1
- package/dist/utils/private/jose-header.js +12 -17
- package/dist/utils/private/jose-header.js.map +1 -1
- package/dist/utils/private/jwt-validate.d.ts +3 -3
- package/dist/utils/private/jwt-validate.d.ts.map +1 -1
- package/dist/utils/private/jwt-validate.js +9 -9
- package/dist/utils/private/jwt-validate.js.map +1 -1
- package/dist/utils/private/jwt-verify.d.ts +3 -3
- package/dist/utils/private/jwt-verify.d.ts.map +1 -1
- package/dist/utils/private/jwt-verify.js +14 -14
- package/dist/utils/private/jwt-verify.js.map +1 -1
- package/dist/utils/private/token-header.d.ts.map +1 -1
- package/dist/utils/private/token-header.js +2 -10
- package/dist/utils/private/token-header.js.map +1 -1
- package/dist/utils/private/validate.d.ts +2 -3
- package/dist/utils/private/validate.d.ts.map +1 -1
- package/dist/utils/private/validate.js +9 -10
- package/dist/utils/private/validate.js.map +1 -1
- package/jest.config.interop.mjs +27 -0
- package/package.json +24 -24
- package/tsconfig.interop.json +9 -0
- package/dist/types/operators.d.ts +0 -27
- package/dist/types/operators.d.ts.map +0 -1
- package/dist/types/operators.js.map +0 -1
- package/dist/utils/private/validate-value.d.ts +0 -3
- package/dist/utils/private/validate-value.d.ts.map +0 -1
- package/dist/utils/private/validate-value.js +0 -91
- package/dist/utils/private/validate-value.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,31 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.4.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.6...@lindorm/aegis@0.4.0) (2026-02-17)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **aegis:** align header parsing types with AES decryption record types ([8d6539d](https://github.com/lindorm-io/monorepo/commit/8d6539d41657343edce4c94c884fe592c9bb12e6))
|
|
11
|
+
- **aegis:** relax algorithm validation in header decoding ([fbc6edc](https://github.com/lindorm-io/monorepo/commit/fbc6edc003849963827c483ff2d995cd5b66eada))
|
|
12
|
+
- **aegis:** relax typ validation and fix kryptosSig algorithm bug ([cb1bb60](https://github.com/lindorm-io/monorepo/commit/cb1bb601e2004de4b0a6454dd60a35be7770f59c))
|
|
13
|
+
- **aegis:** remove hkdfSalt references after aes package refactor ([30c008a](https://github.com/lindorm-io/monorepo/commit/30c008a99a364928ed83fbb7ee6b496691646f80))
|
|
14
|
+
- **aegis:** remove jwksUri from COSE sign/encrypt headers ([2c47fd4](https://github.com/lindorm-io/monorepo/commit/2c47fd43297db43e8f6b98df4b25ee93e93415af))
|
|
15
|
+
- **aegis:** restructure CweKit header layout per RFC 9052 ([43f2616](https://github.com/lindorm-io/monorepo/commit/43f2616b34de529e968f75714a2222ed4d02a509))
|
|
16
|
+
- **aegis:** rFC 7515 crit compliance and base64url header encoding ([f3fa30b](https://github.com/lindorm-io/monorepo/commit/f3fa30b89f10518efa86ad69577e1d1c35faf030))
|
|
17
|
+
- **aegis:** use Map-based COSE encoding for RFC 9052 integer labels ([e2eb229](https://github.com/lindorm-io/monorepo/commit/e2eb229b053c9c91ba8b4b43d8ad9e1731ec53b4))
|
|
18
|
+
- **lint:** add missing eslint-config-prettier and fix prettier formatting ([6899e39](https://github.com/lindorm-io/monorepo/commit/6899e39ad7700e373173b0a61b429b5536c13934))
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
- **aegis:** add COSE target mode for internal/external encoding ([0be6874](https://github.com/lindorm-io/monorepo/commit/0be687457cea0266cefdff8fc504b05175aa8bbf))
|
|
23
|
+
- **aegis:** integrate prepareEncryption for JWE AAD support ([0b5a607](https://github.com/lindorm-io/monorepo/commit/0b5a60749b935068a02c6ae9fa1a637e0bfa8764))
|
|
24
|
+
- **aegis:** narrow AmphoraQuery type by operation ([e908b40](https://github.com/lindorm-io/monorepo/commit/e908b405f5269aaa864f2da5b19879f9d999e485))
|
|
25
|
+
- **aegis:** support custom COSE claim labels (>= 900) in CWT payloads ([a5f30c0](https://github.com/lindorm-io/monorepo/commit/a5f30c09d6ca21dc029a6d2a601ff3cf35b8dff4))
|
|
26
|
+
|
|
27
|
+
## [0.3.6](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.5...@lindorm/aegis@0.3.6) (2025-09-18)
|
|
28
|
+
|
|
29
|
+
**Note:** Version bump only for package @lindorm/aegis
|
|
30
|
+
|
|
6
31
|
## [0.3.5](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.4...@lindorm/aegis@0.3.5) (2025-07-19)
|
|
7
32
|
|
|
8
33
|
**Note:** Version bump only for package @lindorm/aegis
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @lindorm/aegis
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Token operations for JWT, JWE, JWS, CWT (CBOR Web Token), CWS (COSE Sign1), and CWE (COSE Encrypt).
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,254 +8,338 @@ A comprehensive TypeScript library for JWT, JWE, JWS, CBOR Web Token (CWT), COSE
|
|
|
8
8
|
npm install @lindorm/aegis
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Overview
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
- **JWE Operations**: Encrypt and decrypt JSON Web Encryption
|
|
15
|
-
- **JWS Operations**: Sign and verify JSON Web Signatures
|
|
16
|
-
- **CWT Operations**: Sign and verify CBOR Web Tokens
|
|
17
|
-
- **CWS Operations**: Sign and verify COSE Sign messages
|
|
18
|
-
- **CWE Operations**: Encrypt and decrypt COSE Encrypt messages
|
|
19
|
-
- **AES Operations**: AES encryption and decryption with multiple output formats
|
|
20
|
-
- **Static Token Analysis**: Decode, parse, and validate tokens without verification
|
|
21
|
-
- **Universal Verification**: Automatically detect and verify any supported token type
|
|
13
|
+
Aegis provides two usage patterns:
|
|
22
14
|
|
|
23
|
-
|
|
15
|
+
- **Aegis class** — async wrapper that resolves keys from an `IAmphora` key store before delegating to Kit classes.
|
|
16
|
+
- **Kit classes** (`JwtKit`, `CwtKit`, `CwsKit`, etc.) — synchronous, single-key operations. You supply an `IKryptos` key directly.
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
The Aegis class methods are **async** because they perform key lookups. All Kit class methods are **synchronous**.
|
|
26
19
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
import { Logger } from '@lindorm/logger';
|
|
20
|
+
## Aegis Class
|
|
21
|
+
|
|
22
|
+
Async wrapper that resolves keys from an `IAmphora` key store. All operations are async.
|
|
31
23
|
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
```typescript
|
|
25
|
+
import { Aegis } from "@lindorm/aegis";
|
|
34
26
|
|
|
35
27
|
const aegis = new Aegis({
|
|
36
28
|
amphora,
|
|
37
29
|
logger,
|
|
38
|
-
issuer:
|
|
39
|
-
clockTolerance: 30000, //
|
|
30
|
+
issuer: "https://example.com",
|
|
31
|
+
clockTolerance: 30000, // ms, optional
|
|
32
|
+
encryption: "A256GCM", // optional, default "A256GCM"
|
|
33
|
+
encAlgorithm: "ECDH-ES", // optional, default encryption algorithm
|
|
34
|
+
sigAlgorithm: "ES256", // optional, default signing algorithm
|
|
40
35
|
});
|
|
41
|
-
|
|
42
|
-
// Setup and add keys to amphora
|
|
43
|
-
await amphora.setup();
|
|
44
|
-
// amphora.add(kryptosKey);
|
|
45
36
|
```
|
|
46
37
|
|
|
47
|
-
###
|
|
38
|
+
### Namespaced operations
|
|
48
39
|
|
|
49
40
|
```typescript
|
|
50
|
-
//
|
|
51
|
-
const
|
|
52
|
-
expires:
|
|
53
|
-
subject:
|
|
54
|
-
tokenType:
|
|
55
|
-
claims: { name: 'John Doe', admin: true },
|
|
56
|
-
audience: ['https://api.example.com'],
|
|
57
|
-
scope: ['read', 'write']
|
|
41
|
+
// JWT
|
|
42
|
+
const signed = await aegis.jwt.sign({
|
|
43
|
+
expires: "1h",
|
|
44
|
+
subject: "u1",
|
|
45
|
+
tokenType: "access_token",
|
|
58
46
|
});
|
|
47
|
+
const parsed = await aegis.jwt.verify(signed.token);
|
|
59
48
|
|
|
60
|
-
//
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
49
|
+
// CWT
|
|
50
|
+
const cwt = await aegis.cwt.sign({
|
|
51
|
+
expires: "1h",
|
|
52
|
+
subject: "u1",
|
|
53
|
+
tokenType: "access_token",
|
|
64
54
|
});
|
|
65
|
-
|
|
55
|
+
const cwtParsed = await aegis.cwt.verify(cwt.token);
|
|
66
56
|
|
|
67
|
-
|
|
57
|
+
// JWS / CWS — sign and verify arbitrary data
|
|
58
|
+
const jws = await aegis.jws.sign("data");
|
|
59
|
+
const cws = await aegis.cws.sign("data");
|
|
68
60
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
objectId: 'message-123'
|
|
73
|
-
});
|
|
61
|
+
// JWE / CWE — encrypt and decrypt
|
|
62
|
+
const jwe = await aegis.jwe.encrypt("secret");
|
|
63
|
+
const cwe = await aegis.cwe.encrypt("secret");
|
|
74
64
|
|
|
75
|
-
//
|
|
76
|
-
const
|
|
77
|
-
|
|
65
|
+
// AES — returns base64 encoded string by default
|
|
66
|
+
const encoded = await aegis.aes.encrypt("data");
|
|
67
|
+
const record = await aegis.aes.encrypt("data", "record");
|
|
68
|
+
const serialised = await aegis.aes.encrypt("data", "serialised");
|
|
69
|
+
const decrypted = await aegis.aes.decrypt(encoded);
|
|
78
70
|
```
|
|
79
71
|
|
|
80
|
-
###
|
|
72
|
+
### Universal verification
|
|
73
|
+
|
|
74
|
+
Automatically detects token type and verifies/decrypts accordingly.
|
|
81
75
|
|
|
82
76
|
```typescript
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
objectId: 'message-456'
|
|
77
|
+
const result = await aegis.verify(anyToken, {
|
|
78
|
+
audience: "https://api.example.com",
|
|
86
79
|
});
|
|
80
|
+
// Works with JWT, JWE, JWS, CWT, CWE, or CWS
|
|
81
|
+
// JWE/CWE tokens are decrypted, then their inner payload is verified
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Static methods
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
No key or amphora required.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
Aegis.isJwt(token);
|
|
90
|
+
Aegis.isCwt(token);
|
|
91
|
+
Aegis.isJws(token);
|
|
92
|
+
Aegis.isCws(token);
|
|
93
|
+
Aegis.isJwe(token);
|
|
94
|
+
Aegis.isCwe(token);
|
|
95
|
+
|
|
96
|
+
Aegis.header(token); // TokenHeaderClaims (JOSE tokens only)
|
|
97
|
+
Aegis.decode(token); // auto-detect and decode without verification
|
|
98
|
+
Aegis.parse(token); // auto-detect, decode, and validate structure
|
|
91
99
|
```
|
|
92
100
|
|
|
93
|
-
|
|
101
|
+
## Kit Classes
|
|
102
|
+
|
|
103
|
+
### JwtKit
|
|
104
|
+
|
|
105
|
+
Signs and verifies JSON Web Tokens.
|
|
94
106
|
|
|
95
107
|
```typescript
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
108
|
+
import { JwtKit } from "@lindorm/aegis";
|
|
109
|
+
|
|
110
|
+
const kit = new JwtKit({ issuer: "https://example.com", logger, kryptos });
|
|
111
|
+
|
|
112
|
+
// Sign — returns { token, expiresAt, expiresIn, expiresOn, objectId, tokenId }
|
|
113
|
+
const signed = kit.sign({
|
|
114
|
+
expires: "1h",
|
|
115
|
+
subject: "user-123",
|
|
116
|
+
tokenType: "access_token",
|
|
117
|
+
audience: ["https://api.example.com"],
|
|
118
|
+
claims: { role: "admin" },
|
|
119
|
+
scope: ["read", "write"],
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Verify — returns { decoded, header, payload, token }
|
|
123
|
+
const parsed = kit.verify(signed.token, {
|
|
124
|
+
audience: "https://api.example.com",
|
|
125
|
+
scope: ["read"],
|
|
102
126
|
});
|
|
103
127
|
|
|
104
|
-
//
|
|
105
|
-
|
|
128
|
+
// Static methods (no key required)
|
|
129
|
+
JwtKit.isJwt(token); // boolean
|
|
130
|
+
JwtKit.decode(token); // { header, payload, signature }
|
|
131
|
+
JwtKit.parse(token); // { decoded, header, payload, token }
|
|
132
|
+
JwtKit.validate(payload, options); // throws on mismatch
|
|
106
133
|
```
|
|
107
134
|
|
|
108
|
-
###
|
|
135
|
+
### CwtKit
|
|
136
|
+
|
|
137
|
+
Signs and verifies CBOR Web Tokens (RFC 8392). Uses COSE Sign1 structure with CBOR-encoded payloads and integer claim labels.
|
|
109
138
|
|
|
110
139
|
```typescript
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
});
|
|
140
|
+
import { CwtKit } from "@lindorm/aegis";
|
|
141
|
+
|
|
142
|
+
const kit = new CwtKit({ issuer: "https://example.com", logger, kryptos });
|
|
115
143
|
|
|
116
|
-
|
|
117
|
-
|
|
144
|
+
// Sign — returns { buffer, token, expiresAt, expiresIn, expiresOn, objectId, tokenId }
|
|
145
|
+
const signed = kit.sign({
|
|
146
|
+
expires: "1h",
|
|
147
|
+
subject: "user-123",
|
|
148
|
+
tokenType: "access_token",
|
|
149
|
+
claims: { 900: "custom-value", 901: 42 }, // integer labels >= 900
|
|
150
|
+
});
|
|
118
151
|
|
|
119
|
-
//
|
|
120
|
-
const
|
|
121
|
-
|
|
152
|
+
// Verify — accepts Buffer or base64url string
|
|
153
|
+
const parsed = kit.verify(signed.token, {
|
|
154
|
+
tokenType: "access_token",
|
|
122
155
|
});
|
|
123
|
-
|
|
124
|
-
|
|
156
|
+
|
|
157
|
+
// Static methods
|
|
158
|
+
CwtKit.isCwt(token);
|
|
159
|
+
CwtKit.decode(token);
|
|
160
|
+
CwtKit.parse(token);
|
|
161
|
+
CwtKit.validate(payload, options);
|
|
125
162
|
```
|
|
126
163
|
|
|
127
|
-
|
|
164
|
+
**COSE target modes:** Pass `{ target: "external" }` to sign options to emit string keys for proprietary labels instead of integer CBOR labels. Standard RFC claims (iss, sub, exp, etc.) always use integer labels regardless of target.
|
|
165
|
+
|
|
166
|
+
**Custom claim labels:** Numeric keys >= 900 in the `claims` object are encoded as compact integer CBOR labels. Keys below 900 are rejected to prevent collision with IANA-assigned (1-255) and Lindorm-reserved (400-599) ranges.
|
|
167
|
+
|
|
168
|
+
### CwsKit
|
|
169
|
+
|
|
170
|
+
Signs and verifies arbitrary data using COSE Sign1 (RFC 9052).
|
|
128
171
|
|
|
129
172
|
```typescript
|
|
130
|
-
|
|
131
|
-
const encoded = await aegis.aes.encrypt('data'); // Returns base64 encoded string
|
|
132
|
-
const record = await aegis.aes.encrypt('data', 'record'); // Returns AesEncryptionRecord
|
|
133
|
-
const serialised = await aegis.aes.encrypt('data', 'serialised'); // Returns SerialisedAesEncryption
|
|
173
|
+
import { CwsKit } from "@lindorm/aegis";
|
|
134
174
|
|
|
135
|
-
|
|
136
|
-
|
|
175
|
+
const kit = new CwsKit({ logger, kryptos });
|
|
176
|
+
|
|
177
|
+
// Sign string or Buffer — returns { buffer, objectId, token }
|
|
178
|
+
const signed = kit.sign("hello world", {
|
|
179
|
+
objectId: "msg-001",
|
|
180
|
+
target: "internal", // or "external"
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Verify — returns { decoded, header, payload, token }
|
|
184
|
+
const parsed = kit.verify(signed.token);
|
|
185
|
+
// parsed.payload === "hello world"
|
|
186
|
+
|
|
187
|
+
// Static methods
|
|
188
|
+
CwsKit.isCws(token);
|
|
189
|
+
CwsKit.decode(token);
|
|
190
|
+
CwsKit.parse(token);
|
|
137
191
|
```
|
|
138
192
|
|
|
139
|
-
###
|
|
193
|
+
### CweKit
|
|
194
|
+
|
|
195
|
+
Encrypts and decrypts data using COSE Encrypt (RFC 9052).
|
|
140
196
|
|
|
141
197
|
```typescript
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
198
|
+
import { CweKit } from "@lindorm/aegis";
|
|
199
|
+
|
|
200
|
+
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
201
|
+
|
|
202
|
+
// Encrypt string or Buffer — returns { buffer, token }
|
|
203
|
+
const encrypted = kit.encrypt("secret data", {
|
|
204
|
+
objectId: "msg-002",
|
|
205
|
+
target: "internal",
|
|
146
206
|
});
|
|
147
207
|
|
|
148
|
-
//
|
|
149
|
-
|
|
208
|
+
// Decrypt — returns { decoded, header, payload, token }
|
|
209
|
+
const decrypted = kit.decrypt(encrypted.token);
|
|
210
|
+
// decrypted.payload === "secret data"
|
|
211
|
+
|
|
212
|
+
// Static methods
|
|
213
|
+
CweKit.isCwe(token);
|
|
214
|
+
CweKit.decode(token);
|
|
150
215
|
```
|
|
151
216
|
|
|
152
|
-
|
|
217
|
+
### JwsKit
|
|
153
218
|
|
|
154
|
-
|
|
219
|
+
Signs and verifies arbitrary data using JSON Web Signatures.
|
|
155
220
|
|
|
156
221
|
```typescript
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
const isCwt = Aegis.isCwt(token);
|
|
222
|
+
import { JwsKit } from "@lindorm/aegis";
|
|
223
|
+
|
|
224
|
+
const kit = new JwsKit({ logger, kryptos });
|
|
161
225
|
|
|
162
|
-
//
|
|
163
|
-
const
|
|
226
|
+
// Sign string or Buffer — returns { objectId, token }
|
|
227
|
+
const signed = kit.sign("hello world", { objectId: "msg-003" });
|
|
164
228
|
|
|
165
|
-
//
|
|
166
|
-
const parsed =
|
|
229
|
+
// Verify — returns { decoded, header, payload, token }
|
|
230
|
+
const parsed = kit.verify(signed.token);
|
|
167
231
|
|
|
168
|
-
//
|
|
169
|
-
|
|
232
|
+
// Static methods
|
|
233
|
+
JwsKit.isJws(token);
|
|
234
|
+
JwsKit.decode(token);
|
|
235
|
+
JwsKit.parse(token);
|
|
170
236
|
```
|
|
171
237
|
|
|
172
|
-
|
|
238
|
+
### JweKit
|
|
173
239
|
|
|
174
|
-
|
|
240
|
+
Encrypts and decrypts data using JSON Web Encryption.
|
|
175
241
|
|
|
176
242
|
```typescript
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
243
|
+
import { JweKit } from "@lindorm/aegis";
|
|
244
|
+
|
|
245
|
+
const kit = new JweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
246
|
+
|
|
247
|
+
// Encrypt string — returns { token }
|
|
248
|
+
const encrypted = kit.encrypt("secret data", { objectId: "msg-004" });
|
|
249
|
+
|
|
250
|
+
// Decrypt — returns { decoded, header, payload, token }
|
|
251
|
+
const decrypted = kit.decrypt(encrypted.token);
|
|
252
|
+
|
|
253
|
+
// Static methods
|
|
254
|
+
JweKit.isJwe(token);
|
|
255
|
+
JweKit.decode(token);
|
|
186
256
|
```
|
|
187
257
|
|
|
188
|
-
###
|
|
258
|
+
### SignatureKit
|
|
259
|
+
|
|
260
|
+
Low-level signature operations over raw data.
|
|
189
261
|
|
|
190
262
|
```typescript
|
|
191
|
-
|
|
192
|
-
expires: string; // Required: Expiration time ('1h', '30m', etc.)
|
|
193
|
-
subject: string; // Required: Token subject
|
|
194
|
-
tokenType: string; // Required: Type of token
|
|
195
|
-
audience?: string[]; // Token audiences
|
|
196
|
-
scope?: string[]; // OAuth scopes
|
|
197
|
-
claims?: Record<string, any>; // Additional claims
|
|
198
|
-
permissions?: string[]; // User permissions
|
|
199
|
-
roles?: string[]; // User roles
|
|
200
|
-
// ... many other optional fields
|
|
201
|
-
}
|
|
263
|
+
import { SignatureKit } from "@lindorm/aegis";
|
|
202
264
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
265
|
+
const kit = new SignatureKit({ kryptos });
|
|
266
|
+
|
|
267
|
+
const signature = kit.sign(data); // Buffer
|
|
268
|
+
const valid = kit.verify(data, signature); // boolean
|
|
269
|
+
kit.assert(data, signature); // throws if invalid
|
|
270
|
+
kit.format(signature); // string
|
|
209
271
|
```
|
|
210
272
|
|
|
211
|
-
|
|
273
|
+
## Sign Content
|
|
274
|
+
|
|
275
|
+
The `SignJwtContent` / `SignCwtContent` types share the same shape:
|
|
212
276
|
|
|
213
277
|
```typescript
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
subject
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
278
|
+
{
|
|
279
|
+
// Required
|
|
280
|
+
expires: string | Date; // "1h", "30m", Date, etc.
|
|
281
|
+
subject: string;
|
|
282
|
+
tokenType: string;
|
|
283
|
+
|
|
284
|
+
// Optional
|
|
285
|
+
audience?: string[];
|
|
286
|
+
claims?: Record<string, any>; // custom claims (CWT supports integer keys >= 900)
|
|
287
|
+
scope?: string[];
|
|
288
|
+
permissions?: string[];
|
|
289
|
+
roles?: string[];
|
|
290
|
+
clientId?: string;
|
|
291
|
+
grantType?: string;
|
|
292
|
+
tenantId?: string;
|
|
293
|
+
sessionId?: string;
|
|
294
|
+
nonce?: string;
|
|
295
|
+
notBefore?: Date;
|
|
296
|
+
authTime?: Date;
|
|
297
|
+
authContextClass?: string;
|
|
298
|
+
authFactor?: string;
|
|
299
|
+
authMethods?: string[];
|
|
300
|
+
authorizedParty?: string;
|
|
301
|
+
adjustedAccessLevel?: number;
|
|
302
|
+
levelOfAssurance?: number;
|
|
303
|
+
sessionHint?: string;
|
|
304
|
+
subjectHint?: string;
|
|
224
305
|
}
|
|
225
306
|
```
|
|
226
307
|
|
|
227
|
-
##
|
|
308
|
+
## Verify Options
|
|
228
309
|
|
|
229
|
-
|
|
310
|
+
All fields are optional and support `PredicateOperator` for flexible matching:
|
|
230
311
|
|
|
231
312
|
```typescript
|
|
232
|
-
|
|
233
|
-
|
|
313
|
+
kit.verify(token, {
|
|
314
|
+
audience: "https://api.example.com", // exact match
|
|
315
|
+
scope: ["read", "write"], // array contains
|
|
316
|
+
tokenType: { $eq: "access_token" }, // predicate operator
|
|
317
|
+
subject: { $in: ["user-1", "user-2"] }, // set membership
|
|
318
|
+
levelOfAssurance: { $gte: 2 }, // numeric comparison
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Errors
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import {
|
|
326
|
+
AegisError, // base error
|
|
234
327
|
JwtError,
|
|
235
|
-
JweError,
|
|
236
328
|
JwsError,
|
|
329
|
+
JweError,
|
|
237
330
|
CwtError,
|
|
331
|
+
CoseSignError,
|
|
238
332
|
CoseEncryptError,
|
|
239
|
-
|
|
240
|
-
} from '@lindorm/aegis';
|
|
241
|
-
|
|
242
|
-
try {
|
|
243
|
-
const result = await aegis.jwt.verify(token);
|
|
244
|
-
} catch (error) {
|
|
245
|
-
if (error instanceof JwtError) {
|
|
246
|
-
console.log('JWT-specific error:', error.message);
|
|
247
|
-
} else if (error instanceof AegisError) {
|
|
248
|
-
console.log('General Aegis error:', error.message);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
333
|
+
} from "@lindorm/aegis";
|
|
251
334
|
```
|
|
252
335
|
|
|
253
|
-
##
|
|
336
|
+
## Testing
|
|
254
337
|
|
|
255
|
-
|
|
338
|
+
```typescript
|
|
339
|
+
import { createMockAegis } from "@lindorm/aegis";
|
|
256
340
|
|
|
257
|
-
|
|
258
|
-
|
|
341
|
+
const aegis = createMockAegis(); // fully mocked IAegis with jest.fn() stubs
|
|
342
|
+
```
|
|
259
343
|
|
|
260
344
|
## License
|
|
261
345
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// ESM bridge for the cbor package (which is CJS-only).
|
|
2
|
+
// Jest ESM mode cannot resolve named exports from CJS modules,
|
|
3
|
+
// so we load cbor via createRequire and re-export its members.
|
|
4
|
+
//
|
|
5
|
+
// We require the cbor entry point by absolute file path to avoid
|
|
6
|
+
// the moduleNameMapper (which maps "^cbor$" to this very file).
|
|
7
|
+
|
|
8
|
+
import { createRequire } from "module";
|
|
9
|
+
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
const cbor = require("/Users/jonn/Projects/lindorm-monorepo/node_modules/cbor/lib/cbor.js");
|
|
12
|
+
|
|
13
|
+
export const encode = cbor.encode;
|
|
14
|
+
export const decode = cbor.decode;
|
|
15
|
+
export const decodeFirst = cbor.decodeFirst;
|
|
16
|
+
export const Encoder = cbor.Encoder;
|
|
17
|
+
export const Decoder = cbor.Decoder;
|