@lindorm/aegis 0.7.0 → 0.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lindorm/aegis",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "author": "Jonn Nilsson",
6
6
  "repository": {
@@ -11,6 +11,9 @@
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
14
+ "files": [
15
+ "dist"
16
+ ],
14
17
  "type": "module",
15
18
  "typings": "dist/index.d.ts",
16
19
  "exports": {
@@ -41,20 +44,20 @@
41
44
  "verify": "npm run typecheck && npm run build && npm test"
42
45
  },
43
46
  "dependencies": {
44
- "@lindorm/aes": "^0.7.0",
45
- "@lindorm/akp": "^0.2.0",
46
- "@lindorm/b64": "^0.2.0",
47
- "@lindorm/date": "^0.5.0",
48
- "@lindorm/ec": "^0.3.0",
49
- "@lindorm/errors": "^0.2.0",
50
- "@lindorm/is": "^0.2.0",
51
- "@lindorm/kryptos": "^0.8.0",
52
- "@lindorm/oct": "^0.3.0",
53
- "@lindorm/okp": "^0.3.0",
54
- "@lindorm/rsa": "^0.3.0",
55
- "@lindorm/sha": "^0.5.0",
56
- "@lindorm/types": "^0.6.0",
57
- "@lindorm/utils": "^0.8.0",
47
+ "@lindorm/aes": "^0.7.1",
48
+ "@lindorm/akp": "^0.2.1",
49
+ "@lindorm/b64": "^0.2.1",
50
+ "@lindorm/date": "^0.5.1",
51
+ "@lindorm/ec": "^0.3.1",
52
+ "@lindorm/errors": "^0.2.1",
53
+ "@lindorm/is": "^0.2.1",
54
+ "@lindorm/kryptos": "^0.8.1",
55
+ "@lindorm/oct": "^0.3.1",
56
+ "@lindorm/okp": "^0.3.1",
57
+ "@lindorm/rsa": "^0.3.1",
58
+ "@lindorm/sha": "^0.5.1",
59
+ "@lindorm/types": "^0.6.1",
60
+ "@lindorm/utils": "^0.8.1",
58
61
  "cbor": "^10.0.12"
59
62
  },
60
63
  "peerDependencies": {
@@ -63,11 +66,11 @@
63
66
  },
64
67
  "devDependencies": {
65
68
  "@auth0/cose": "^1.0.2",
66
- "@lindorm/amphora": "^0.5.0",
67
- "@lindorm/logger": "^0.6.0",
69
+ "@lindorm/amphora": "^0.5.2",
70
+ "@lindorm/logger": "^0.6.2",
68
71
  "@types/jsonwebtoken": "^9.0.10",
69
72
  "jose": "^6.2.1",
70
73
  "jsonwebtoken": "^9.0.3"
71
74
  },
72
- "gitHead": "a2b0a53295aebda806b4057f34707e8583570265"
75
+ "gitHead": "da067071d415e07d7d25bbac1621b9e02fcc3166"
73
76
  }
package/CHANGELOG.md DELETED
@@ -1,185 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- # [0.7.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.6.0...@lindorm/aegis@0.7.0) (2026-05-02)
7
-
8
- ### Bug Fixes
9
-
10
- - **aegis:** drop createRequire interop workaround in jwt-interop test ([492e3df](https://github.com/lindorm-io/monorepo/commit/492e3dff29971a3958b0628ce5465195f8a8cfe5))
11
- - widen @lindorm/\* peer ranges to unbounded >= ([f192b59](https://github.com/lindorm-io/monorepo/commit/f192b59107bf1f276d296837f40fa97765d9d2ba))
12
-
13
- ### Features
14
-
15
- - migrate 20 packages from jest to vitest ([d8bfda8](https://github.com/lindorm-io/monorepo/commit/d8bfda8854dc1cb9537ba0b3e47ec4e4c7bded08))
16
-
17
- # [0.6.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.5.0...@lindorm/aegis@0.6.0) (2026-04-19)
18
-
19
- ### Features
20
-
21
- - **aegis:** accept AKP algorithms in token header ([3dc40b7](https://github.com/lindorm-io/monorepo/commit/3dc40b781f436181a6453235d8f4dc7c61885e7d))
22
- - **aegis:** route AKP kryptos keys through AkpKit for ML-DSA JWS ([a9351fc](https://github.com/lindorm-io/monorepo/commit/a9351fc94e47de240d51f2024a418111e762f046))
23
-
24
- # [0.5.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.4.4...@lindorm/aegis@0.5.0) (2026-04-15)
25
-
26
- ### Bug Fixes
27
-
28
- - **aegis:** accept AesContent in IAegisAes types, delegate mock to AesKit ([11b78df](https://github.com/lindorm-io/monorepo/commit/11b78df01112106280466a1824a8c47151ceee65))
29
- - **aegis:** adopt kryptos descriptive cert fields and drop SHA-1 x5t binding ([06e4d4d](https://github.com/lindorm-io/monorepo/commit/06e4d4dd4bc2f3311370335316d1ffb27df0a317))
30
- - **aegis:** resolve historical kryptos by id when verifying JWE/JWS ([24c81d4](https://github.com/lindorm-io/monorepo/commit/24c81d4dfa2da67eafcc6e1af432af1a75567b16))
31
- - **aegis:** string verifier for array-valued claims uses containment ([7cc2c7e](https://github.com/lindorm-io/monorepo/commit/7cc2c7e32140a29ffddd079f956dee9e611ae03c))
32
-
33
- ### Features
34
-
35
- - **aegis:** add act, may_act, groups, entitlements claim types ([ed80767](https://github.com/lindorm-io/monorepo/commit/ed80767a029fded720bb9af44fb3cdeb2b5c30d6))
36
- - **aegis:** add AegisProfile claim type for ID token profile personalization ([929a9b6](https://github.com/lindorm-io/monorepo/commit/929a9b6ee7b051d50dda8aa8c6a1c3e88e23e4d5))
37
- - **aegis:** add baseFormat to parsed token headers ([43d37a0](https://github.com/lindorm-io/monorepo/commit/43d37a02a3ae1773fb166aabd7f7957dcf30e4ac))
38
- - **aegis:** add bindCertificate sign option and post-verify thumbprint check ([0d4e2a5](https://github.com/lindorm-io/monorepo/commit/0d4e2a5bdfbfa745b7b3e137ecf4b4a617c6d8f5)), closes [x5t#S256](https://github.com/x5t/issues/S256)
39
- - **aegis:** add certBindingMode strict/lax for cert-binding verify ([bfd2165](https://github.com/lindorm-io/monorepo/commit/bfd2165d65a1bdb0895e503466dfc287259f7a66))
40
- - **aegis:** add cnf claim support on sign and parse ([e7d7a28](https://github.com/lindorm-io/monorepo/commit/e7d7a28d1b82cf711c54d64aa51f2615b96c1e4d))
41
- - **aegis:** add isParsedJwt and isParsedJws guards ([1640977](https://github.com/lindorm-io/monorepo/commit/1640977405de7bc183e98b24857ce33cc21ad0d4))
42
- - **aegis:** add TokenType, AuthFactor, SessionHint, SubjectHint types ([fb7a15a](https://github.com/lindorm-io/monorepo/commit/fb7a15a2687ed0e1126ac94c23ed01472d0fa044))
43
- - **aegis:** add userinfo and introspection parse utilities ([ab2e14f](https://github.com/lindorm-io/monorepo/commit/ab2e14f4ef0b40c7a70ad0fe08079a88c99c5f33))
44
- - **aegis:** attach TokenIdentity to parsed results and add actor verify option ([7bcfdae](https://github.com/lindorm-io/monorepo/commit/7bcfdae0d4d1c83811ea8e03437fb284113f69e4))
45
- - **aegis:** auto-stamp thumbprint on sign when kryptos has cert, add none mode ([441630f](https://github.com/lindorm-io/monorepo/commit/441630f177b4264a791da9ce9e5409b4de15958a))
46
- - **aegis:** enforce algorithm allowlist in decodeJoseHeader ([5be80a1](https://github.com/lindorm-io/monorepo/commit/5be80a10aa7461323e1b620bed8a699f960e7089)), closes [PKCS#1](https://github.com/PKCS/issues/1)
47
- - **aegis:** expose parseUserinfo, parseIntrospection, and validateClaims on Aegis ([a29ec9c](https://github.com/lindorm-io/monorepo/commit/a29ec9c3568631c067d0984de07769a969ca1719))
48
- - **aegis:** reject JWE tokens with zip compression header ([644d37d](https://github.com/lindorm-io/monorepo/commit/644d37debea9a5bf0edab469ced8e2bc6467bf60))
49
- - **aegis:** validate tokenType input in computeTypHeader ([5d95fb6](https://github.com/lindorm-io/monorepo/commit/5d95fb69ab5625cd6812b5b29be91c436f8001a0))
50
- - **aegis:** verify DPoP proofs as part of JWT verification ([9795b7c](https://github.com/lindorm-io/monorepo/commit/9795b7c1d0b8925050fe82176515a47aeefd5957))
51
-
52
- ## [0.4.4](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.4.3...@lindorm/aegis@0.4.4) (2026-04-01)
53
-
54
- **Note:** Version bump only for package @lindorm/aegis
55
-
56
- ## [0.4.3](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.4.2...@lindorm/aegis@0.4.3) (2026-03-29)
57
-
58
- **Note:** Version bump only for package @lindorm/aegis
59
-
60
- ## [0.4.2](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.4.1...@lindorm/aegis@0.4.2) (2026-03-13)
61
-
62
- **Note:** Version bump only for package @lindorm/aegis
63
-
64
- ## [0.4.1](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.4.0...@lindorm/aegis@0.4.1) (2026-03-13)
65
-
66
- **Note:** Version bump only for package @lindorm/aegis
67
-
68
- # [0.4.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.6...@lindorm/aegis@0.4.0) (2026-02-17)
69
-
70
- ### Bug Fixes
71
-
72
- - **aegis:** align header parsing types with AES decryption record types ([8d6539d](https://github.com/lindorm-io/monorepo/commit/8d6539d41657343edce4c94c884fe592c9bb12e6))
73
- - **aegis:** relax algorithm validation in header decoding ([fbc6edc](https://github.com/lindorm-io/monorepo/commit/fbc6edc003849963827c483ff2d995cd5b66eada))
74
- - **aegis:** relax typ validation and fix kryptosSig algorithm bug ([cb1bb60](https://github.com/lindorm-io/monorepo/commit/cb1bb601e2004de4b0a6454dd60a35be7770f59c))
75
- - **aegis:** remove hkdfSalt references after aes package refactor ([30c008a](https://github.com/lindorm-io/monorepo/commit/30c008a99a364928ed83fbb7ee6b496691646f80))
76
- - **aegis:** remove jwksUri from COSE sign/encrypt headers ([2c47fd4](https://github.com/lindorm-io/monorepo/commit/2c47fd43297db43e8f6b98df4b25ee93e93415af))
77
- - **aegis:** restructure CweKit header layout per RFC 9052 ([43f2616](https://github.com/lindorm-io/monorepo/commit/43f2616b34de529e968f75714a2222ed4d02a509))
78
- - **aegis:** rFC 7515 crit compliance and base64url header encoding ([f3fa30b](https://github.com/lindorm-io/monorepo/commit/f3fa30b89f10518efa86ad69577e1d1c35faf030))
79
- - **aegis:** use Map-based COSE encoding for RFC 9052 integer labels ([e2eb229](https://github.com/lindorm-io/monorepo/commit/e2eb229b053c9c91ba8b4b43d8ad9e1731ec53b4))
80
- - **lint:** add missing eslint-config-prettier and fix prettier formatting ([6899e39](https://github.com/lindorm-io/monorepo/commit/6899e39ad7700e373173b0a61b429b5536c13934))
81
-
82
- ### Features
83
-
84
- - **aegis:** add COSE target mode for internal/external encoding ([0be6874](https://github.com/lindorm-io/monorepo/commit/0be687457cea0266cefdff8fc504b05175aa8bbf))
85
- - **aegis:** integrate prepareEncryption for JWE AAD support ([0b5a607](https://github.com/lindorm-io/monorepo/commit/0b5a60749b935068a02c6ae9fa1a637e0bfa8764))
86
- - **aegis:** narrow AmphoraQuery type by operation ([e908b40](https://github.com/lindorm-io/monorepo/commit/e908b405f5269aaa864f2da5b19879f9d999e485))
87
- - **aegis:** support custom COSE claim labels (>= 900) in CWT payloads ([a5f30c0](https://github.com/lindorm-io/monorepo/commit/a5f30c09d6ca21dc029a6d2a601ff3cf35b8dff4))
88
-
89
- ## [0.3.6](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.5...@lindorm/aegis@0.3.6) (2025-09-18)
90
-
91
- **Note:** Version bump only for package @lindorm/aegis
92
-
93
- ## [0.3.5](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.4...@lindorm/aegis@0.3.5) (2025-07-19)
94
-
95
- **Note:** Version bump only for package @lindorm/aegis
96
-
97
- ## [0.3.4](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.3...@lindorm/aegis@0.3.4) (2025-07-12)
98
-
99
- **Note:** Version bump only for package @lindorm/aegis
100
-
101
- ## [0.3.3](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.2...@lindorm/aegis@0.3.3) (2025-07-10)
102
-
103
- **Note:** Version bump only for package @lindorm/aegis
104
-
105
- ## [0.3.2](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.1...@lindorm/aegis@0.3.2) (2025-07-02)
106
-
107
- **Note:** Version bump only for package @lindorm/aegis
108
-
109
- ## [0.3.1](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.3.0...@lindorm/aegis@0.3.1) (2025-06-24)
110
-
111
- **Note:** Version bump only for package @lindorm/aegis
112
-
113
- # [0.3.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.2.6...@lindorm/aegis@0.3.0) (2025-06-17)
114
-
115
- ### Bug Fixes
116
-
117
- - add missing header options to sign and encrypt ([d0007e7](https://github.com/lindorm-io/monorepo/commit/d0007e70c0afcf5945b223b27e7b8c02c07b3109))
118
- - add missing jwt options for verify ([c5b9439](https://github.com/lindorm-io/monorepo/commit/c5b9439b41a7de541e966c350102b7cffde389b5))
119
- - add optional key filter for aegis ([49a6d75](https://github.com/lindorm-io/monorepo/commit/49a6d75a89f435c40389fbee00840c011e369b00))
120
- - align with kryptos changes ([206eb38](https://github.com/lindorm-io/monorepo/commit/206eb38ae2a03b14973e706035c87a953cc753af))
121
- - amend bugs ([a68a77a](https://github.com/lindorm-io/monorepo/commit/a68a77a811ddfe33a0b487cd84cda6a18d3054b6))
122
- - amend errors in mock ([4e80b28](https://github.com/lindorm-io/monorepo/commit/4e80b28e2bd35ae7ae43da9d3b480bae935aef08))
123
- - handle correct typing ([630fa33](https://github.com/lindorm-io/monorepo/commit/630fa332c16557fa5f16c3cc673af563d5ea4e24))
124
- - improve content type method ([d12f1fd](https://github.com/lindorm-io/monorepo/commit/d12f1fd4484c5e6b1becbdd72feed010d2c5cd98))
125
- - merge domain with issuer for ease of understanding ([9123cc2](https://github.com/lindorm-io/monorepo/commit/9123cc2ede63962a5c226a9bed0d0541001384d9))
126
- - minor improvements ([0f7db68](https://github.com/lindorm-io/monorepo/commit/0f7db68cddefce258434258ea9f6c0d5f5ba4fc4))
127
- - rename kits ([da103bf](https://github.com/lindorm-io/monorepo/commit/da103bf21fc25f3477dd9b70a851e4bca5758283))
128
- - update types and fallback to amphora issuer ([8130b45](https://github.com/lindorm-io/monorepo/commit/8130b45bc7a1c2080e029e6e2efc8c58a65f1d7e))
129
-
130
- ### Features
131
-
132
- - add aegis aes and improve key methods ([ac1800e](https://github.com/lindorm-io/monorepo/commit/ac1800e65f1e9fc82814bb84793678f8c3fd1f8d))
133
- - add decode and verify to aegis ([bd6c9c3](https://github.com/lindorm-io/monorepo/commit/bd6c9c3b041eb0ed398d01f8d52b44e74cbad429))
134
- - add signature kit ([ca99771](https://github.com/lindorm-io/monorepo/commit/ca99771955b69a41a1add2cbad6a9512783f54ab))
135
- - add static token parsing to aegis ([2b8803c](https://github.com/lindorm-io/monorepo/commit/2b8803c189ce2bc97fe49c977e6fbb58cace13f7))
136
- - implement cose-encrypt kit ([5f94faf](https://github.com/lindorm-io/monorepo/commit/5f94fafc28ab737b02cb3e7566da0d5c827d8c1a))
137
- - implement cose-sign kit ([fd92fa3](https://github.com/lindorm-io/monorepo/commit/fd92fa346401de76967f5d3c0cc5fd6531e4b4bd))
138
- - introduce cwt to aegis ([40a7efa](https://github.com/lindorm-io/monorepo/commit/40a7efa1ce2907c0e4671d20cd9d9fb457a346db))
139
-
140
- ## [0.2.6](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.2.5...@lindorm/aegis@0.2.6) (2025-01-28)
141
-
142
- **Note:** Version bump only for package @lindorm/aegis
143
-
144
- ## [0.2.5](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.2.4...@lindorm/aegis@0.2.5) (2024-10-12)
145
-
146
- **Note:** Version bump only for package @lindorm/aegis
147
-
148
- ## [0.2.4](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.2.3...@lindorm/aegis@0.2.4) (2024-10-09)
149
-
150
- ### Bug Fixes
151
-
152
- - align with aes changes ([f49b8c0](https://github.com/lindorm-io/monorepo/commit/f49b8c01cb8893e624da046832965bf64889117b))
153
-
154
- ## [0.2.3](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.2.2...@lindorm/aegis@0.2.3) (2024-09-25)
155
-
156
- **Note:** Version bump only for package @lindorm/aegis
157
-
158
- ## [0.2.2](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.2.1...@lindorm/aegis@0.2.2) (2024-09-23)
159
-
160
- **Note:** Version bump only for package @lindorm/aegis
161
-
162
- ## [0.2.1](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.2.0...@lindorm/aegis@0.2.1) (2024-09-20)
163
-
164
- ### Bug Fixes
165
-
166
- - make issuer optional ([6e85927](https://github.com/lindorm-io/monorepo/commit/6e859272370e59dc334aca702fa37e1765f542ab))
167
- - return token on verify ([8bad0e0](https://github.com/lindorm-io/monorepo/commit/8bad0e02cb7979c9462387fcb62026e9e895643c))
168
-
169
- # [0.2.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.1.1...@lindorm/aegis@0.2.0) (2024-05-20)
170
-
171
- ### Features
172
-
173
- - use amphora ([d61acf7](https://github.com/lindorm-io/monorepo/commit/d61acf7f7de762f0a4980b9dd720ec62a5787ba1))
174
-
175
- ## [0.1.1](https://github.com/lindorm-io/monorepo/compare/@lindorm/aegis@0.1.0...@lindorm/aegis@0.1.1) (2024-05-20)
176
-
177
- ### Bug Fixes
178
-
179
- - update jwe with gcm keywrap ([0abbd3b](https://github.com/lindorm-io/monorepo/commit/0abbd3b26120dabe8e71223ea45b7c9beb14d4e9))
180
-
181
- # 0.1.0 (2024-05-19)
182
-
183
- ### Features
184
-
185
- - initialise aegis package ([b0eb954](https://github.com/lindorm-io/monorepo/commit/b0eb954d9015bd965a3120980edaceaff55e9ccb))
@@ -1,332 +0,0 @@
1
- import { KryptosKit } from "@lindorm/kryptos";
2
- import { createMockLogger } from "@lindorm/logger/mocks/vitest";
3
- import { CompactEncrypt, compactDecrypt, importJWK } from "jose";
4
- import { JweKit } from "../src/classes/JweKit.js";
5
- import { describe, expect, test } from "vitest";
6
-
7
- // ---------------------------------------------------------------------------
8
- // Shared constants
9
- // ---------------------------------------------------------------------------
10
-
11
- const PLAINTEXT = "hello aegis jwe interop";
12
- const logger = createMockLogger();
13
-
14
- // ---------------------------------------------------------------------------
15
- // Key generation helpers
16
- // ---------------------------------------------------------------------------
17
-
18
- const createOctKwKey = () => KryptosKit.generate.enc.oct({ algorithm: "A128KW" });
19
-
20
- const createOctDirKey = (encryption: "A256GCM" | "A128GCM" = "A256GCM") =>
21
- KryptosKit.generate.enc.oct({ algorithm: "dir", encryption });
22
-
23
- const createRsaOaepKey = () => KryptosKit.generate.enc.rsa({ algorithm: "RSA-OAEP-256" });
24
-
25
- const createEcdhEsKey = () =>
26
- KryptosKit.generate.enc.ec({ algorithm: "ECDH-ES", curve: "P-256" });
27
-
28
- // ---------------------------------------------------------------------------
29
- // Helper: export public-only JWK for jose encryption
30
- // ---------------------------------------------------------------------------
31
-
32
- const toPublicJwk = (jwk: Record<string, unknown>): Record<string, unknown> => {
33
- const { d, dp, dq, p, q, qi, ...publicParts } = jwk as any;
34
- return publicParts;
35
- };
36
-
37
- // ---------------------------------------------------------------------------
38
- // A128KW + A128GCM
39
- // ---------------------------------------------------------------------------
40
-
41
- describe("JWE interop: aegis <-> jose", () => {
42
- describe("A128KW + A128GCM", () => {
43
- test("aegis encrypt -> jose decrypt", async () => {
44
- const kryptos = createOctKwKey();
45
- const kit = new JweKit({ logger, kryptos, encryption: "A128GCM" });
46
-
47
- const { token } = kit.encrypt(PLAINTEXT);
48
-
49
- const jwk = kryptos.export("jwk");
50
- const joseKey = await importJWK(jwk, "A128KW");
51
-
52
- const result = await compactDecrypt(token, joseKey);
53
-
54
- expect(new TextDecoder().decode(result.plaintext)).toBe(PLAINTEXT);
55
- expect(result.protectedHeader.alg).toBe("A128KW");
56
- expect(result.protectedHeader.enc).toBe("A128GCM");
57
- });
58
-
59
- test("jose encrypt -> aegis decrypt", async () => {
60
- const kryptos = createOctKwKey();
61
- const kit = new JweKit({ logger, kryptos, encryption: "A128GCM" });
62
-
63
- const jwk = kryptos.export("jwk");
64
- const joseKey = await importJWK(jwk, "A128KW");
65
-
66
- const token = await new CompactEncrypt(new TextEncoder().encode(PLAINTEXT))
67
- .setProtectedHeader({
68
- alg: "A128KW",
69
- enc: "A128GCM",
70
- typ: "JWE",
71
- kid: kryptos.id,
72
- cty: "text/plain; charset=utf-8",
73
- })
74
- .encrypt(joseKey);
75
-
76
- const result = kit.decrypt(token);
77
-
78
- expect(result.payload).toBe(PLAINTEXT);
79
- expect(result.header.algorithm).toBe("A128KW");
80
- expect(result.header.encryption).toBe("A128GCM");
81
- });
82
- });
83
-
84
- // ---------------------------------------------------------------------------
85
- // A128KW + A256GCM
86
- // ---------------------------------------------------------------------------
87
-
88
- describe("A128KW + A256GCM", () => {
89
- test("aegis encrypt -> jose decrypt", async () => {
90
- const kryptos = createOctKwKey();
91
- const kit = new JweKit({ logger, kryptos, encryption: "A256GCM" });
92
-
93
- const { token } = kit.encrypt(PLAINTEXT);
94
-
95
- const jwk = kryptos.export("jwk");
96
- const joseKey = await importJWK(jwk, "A128KW");
97
-
98
- const result = await compactDecrypt(token, joseKey);
99
-
100
- expect(new TextDecoder().decode(result.plaintext)).toBe(PLAINTEXT);
101
- });
102
-
103
- test("jose encrypt -> aegis decrypt", async () => {
104
- const kryptos = createOctKwKey();
105
- const kit = new JweKit({ logger, kryptos, encryption: "A256GCM" });
106
-
107
- const jwk = kryptos.export("jwk");
108
- const joseKey = await importJWK(jwk, "A128KW");
109
-
110
- const token = await new CompactEncrypt(new TextEncoder().encode(PLAINTEXT))
111
- .setProtectedHeader({
112
- alg: "A128KW",
113
- enc: "A256GCM",
114
- typ: "JWE",
115
- kid: kryptos.id,
116
- cty: "text/plain; charset=utf-8",
117
- })
118
- .encrypt(joseKey);
119
-
120
- const result = kit.decrypt(token);
121
-
122
- expect(result.payload).toBe(PLAINTEXT);
123
- });
124
- });
125
-
126
- // ---------------------------------------------------------------------------
127
- // RSA-OAEP-256 + A256GCM
128
- // ---------------------------------------------------------------------------
129
-
130
- describe("RSA-OAEP-256 + A256GCM", () => {
131
- test("aegis encrypt -> jose decrypt", async () => {
132
- const kryptos = createRsaOaepKey();
133
- const kit = new JweKit({ logger, kryptos, encryption: "A256GCM" });
134
-
135
- const { token } = kit.encrypt(PLAINTEXT);
136
-
137
- // jose needs private key for RSA decryption
138
- const jwk = kryptos.export("jwk");
139
- const joseKey = await importJWK(jwk, "RSA-OAEP-256");
140
-
141
- const result = await compactDecrypt(token, joseKey);
142
-
143
- expect(new TextDecoder().decode(result.plaintext)).toBe(PLAINTEXT);
144
- expect(result.protectedHeader.alg).toBe("RSA-OAEP-256");
145
- expect(result.protectedHeader.enc).toBe("A256GCM");
146
- });
147
-
148
- test("jose encrypt -> aegis decrypt", async () => {
149
- const kryptos = createRsaOaepKey();
150
- const kit = new JweKit({ logger, kryptos, encryption: "A256GCM" });
151
-
152
- // jose encrypts with public key
153
- const jwk = kryptos.export("jwk");
154
- const publicJwk = toPublicJwk(jwk);
155
- const joseKey = await importJWK(publicJwk, "RSA-OAEP-256");
156
-
157
- const token = await new CompactEncrypt(new TextEncoder().encode(PLAINTEXT))
158
- .setProtectedHeader({
159
- alg: "RSA-OAEP-256",
160
- enc: "A256GCM",
161
- typ: "JWE",
162
- kid: kryptos.id,
163
- cty: "text/plain; charset=utf-8",
164
- })
165
- .encrypt(joseKey);
166
-
167
- const result = kit.decrypt(token);
168
-
169
- expect(result.payload).toBe(PLAINTEXT);
170
- expect(result.header.algorithm).toBe("RSA-OAEP-256");
171
- expect(result.header.encryption).toBe("A256GCM");
172
- });
173
- });
174
-
175
- // ---------------------------------------------------------------------------
176
- // RSA-OAEP-256 + A128CBC-HS256
177
- // ---------------------------------------------------------------------------
178
-
179
- describe("RSA-OAEP-256 + A128CBC-HS256", () => {
180
- test("aegis encrypt -> jose decrypt", async () => {
181
- const kryptos = createRsaOaepKey();
182
- const kit = new JweKit({ logger, kryptos, encryption: "A128CBC-HS256" });
183
-
184
- const { token } = kit.encrypt(PLAINTEXT);
185
-
186
- const jwk = kryptos.export("jwk");
187
- const joseKey = await importJWK(jwk, "RSA-OAEP-256");
188
-
189
- const result = await compactDecrypt(token, joseKey);
190
-
191
- expect(new TextDecoder().decode(result.plaintext)).toBe(PLAINTEXT);
192
- expect(result.protectedHeader.enc).toBe("A128CBC-HS256");
193
- });
194
-
195
- test("jose encrypt -> aegis decrypt", async () => {
196
- const kryptos = createRsaOaepKey();
197
- const kit = new JweKit({ logger, kryptos, encryption: "A128CBC-HS256" });
198
-
199
- const jwk = kryptos.export("jwk");
200
- const publicJwk = toPublicJwk(jwk);
201
- const joseKey = await importJWK(publicJwk, "RSA-OAEP-256");
202
-
203
- const token = await new CompactEncrypt(new TextEncoder().encode(PLAINTEXT))
204
- .setProtectedHeader({
205
- alg: "RSA-OAEP-256",
206
- enc: "A128CBC-HS256",
207
- typ: "JWE",
208
- kid: kryptos.id,
209
- cty: "text/plain; charset=utf-8",
210
- })
211
- .encrypt(joseKey);
212
-
213
- const result = kit.decrypt(token);
214
-
215
- expect(result.payload).toBe(PLAINTEXT);
216
- expect(result.header.encryption).toBe("A128CBC-HS256");
217
- });
218
- });
219
-
220
- // ---------------------------------------------------------------------------
221
- // A128KW + A128CBC-HS256
222
- // ---------------------------------------------------------------------------
223
-
224
- describe("A128KW + A128CBC-HS256", () => {
225
- test("aegis encrypt -> jose decrypt", async () => {
226
- const kryptos = createOctKwKey();
227
- const kit = new JweKit({ logger, kryptos, encryption: "A128CBC-HS256" });
228
-
229
- const { token } = kit.encrypt(PLAINTEXT);
230
-
231
- const jwk = kryptos.export("jwk");
232
- const joseKey = await importJWK(jwk, "A128KW");
233
-
234
- const result = await compactDecrypt(token, joseKey);
235
-
236
- expect(new TextDecoder().decode(result.plaintext)).toBe(PLAINTEXT);
237
- expect(result.protectedHeader.enc).toBe("A128CBC-HS256");
238
- });
239
-
240
- test("jose encrypt -> aegis decrypt", async () => {
241
- const kryptos = createOctKwKey();
242
- const kit = new JweKit({ logger, kryptos, encryption: "A128CBC-HS256" });
243
-
244
- const jwk = kryptos.export("jwk");
245
- const joseKey = await importJWK(jwk, "A128KW");
246
-
247
- const token = await new CompactEncrypt(new TextEncoder().encode(PLAINTEXT))
248
- .setProtectedHeader({
249
- alg: "A128KW",
250
- enc: "A128CBC-HS256",
251
- typ: "JWE",
252
- kid: kryptos.id,
253
- cty: "text/plain; charset=utf-8",
254
- })
255
- .encrypt(joseKey);
256
-
257
- const result = kit.decrypt(token);
258
-
259
- expect(result.payload).toBe(PLAINTEXT);
260
- expect(result.header.encryption).toBe("A128CBC-HS256");
261
- });
262
- });
263
-
264
- // ---------------------------------------------------------------------------
265
- // dir + A256GCM
266
- // ---------------------------------------------------------------------------
267
-
268
- describe("dir + A256GCM", () => {
269
- test("aegis encrypt -> jose decrypt", async () => {
270
- const kryptos = createOctDirKey("A256GCM");
271
- const kit = new JweKit({ logger, kryptos, encryption: "A256GCM" });
272
-
273
- const { token } = kit.encrypt(PLAINTEXT);
274
-
275
- const jwk = kryptos.export("jwk");
276
- const joseKey = await importJWK(jwk, "dir");
277
-
278
- const result = await compactDecrypt(token, joseKey);
279
-
280
- expect(new TextDecoder().decode(result.plaintext)).toBe(PLAINTEXT);
281
- expect(result.protectedHeader.alg).toBe("dir");
282
- expect(result.protectedHeader.enc).toBe("A256GCM");
283
- });
284
-
285
- test("jose encrypt -> aegis decrypt", async () => {
286
- const kryptos = createOctDirKey("A256GCM");
287
- const kit = new JweKit({ logger, kryptos, encryption: "A256GCM" });
288
-
289
- const jwk = kryptos.export("jwk");
290
- const joseKey = await importJWK(jwk, "dir");
291
-
292
- const token = await new CompactEncrypt(new TextEncoder().encode(PLAINTEXT))
293
- .setProtectedHeader({
294
- alg: "dir",
295
- enc: "A256GCM",
296
- typ: "JWE",
297
- kid: kryptos.id,
298
- cty: "text/plain; charset=utf-8",
299
- })
300
- .encrypt(joseKey);
301
-
302
- const result = kit.decrypt(token);
303
-
304
- expect(result.payload).toBe(PLAINTEXT);
305
- expect(result.header.algorithm).toBe("dir");
306
- expect(result.header.encryption).toBe("A256GCM");
307
- });
308
- });
309
-
310
- // ---------------------------------------------------------------------------
311
- // ECDH-ES + A256GCM (EC P-256)
312
- // ---------------------------------------------------------------------------
313
-
314
- describe("ECDH-ES + A256GCM", () => {
315
- test("aegis encrypt -> jose decrypt", async () => {
316
- const kryptos = createEcdhEsKey();
317
- const kit = new JweKit({ logger, kryptos, encryption: "A256GCM" });
318
-
319
- const { token } = kit.encrypt(PLAINTEXT);
320
-
321
- // jose needs private key for ECDH-ES decryption
322
- const jwk = kryptos.export("jwk");
323
- const joseKey = await importJWK(jwk, "ECDH-ES");
324
-
325
- const result = await compactDecrypt(token, joseKey);
326
-
327
- expect(new TextDecoder().decode(result.plaintext)).toBe(PLAINTEXT);
328
- expect(result.protectedHeader.alg).toBe("ECDH-ES");
329
- expect(result.protectedHeader.enc).toBe("A256GCM");
330
- });
331
- });
332
- });
@@ -1,183 +0,0 @@
1
- import { KryptosKit } from "@lindorm/kryptos";
2
- import { createMockLogger } from "@lindorm/logger/mocks/vitest";
3
- import { importJWK, jwtVerify, SignJWT } from "jose";
4
- import jsonwebtoken, { type JwtPayload } from "jsonwebtoken";
5
- import { JwtKit } from "../src/classes/JwtKit.js";
6
- import { describe, expect, test } from "vitest";
7
-
8
- // ---------------------------------------------------------------------------
9
- // Shared constants
10
- // ---------------------------------------------------------------------------
11
-
12
- const ISSUER = "https://interop.test.lindorm.io/";
13
- const SUBJECT = "d4e5f6a7-b8c9-4d0e-1a2b-3c4d5e6f7890";
14
- const logger = createMockLogger();
15
-
16
- // ---------------------------------------------------------------------------
17
- // Key generation helpers
18
- // ---------------------------------------------------------------------------
19
-
20
- const createEcSigKey = () =>
21
- KryptosKit.generate.sig.ec({ algorithm: "ES256", curve: "P-256" });
22
-
23
- const createRsaSigKey = () => KryptosKit.generate.sig.rsa({ algorithm: "RS256" });
24
-
25
- const createOctSigKey = () => KryptosKit.generate.sig.oct({ algorithm: "HS256" });
26
-
27
- // ---------------------------------------------------------------------------
28
- // Helper: export public-only JWK for jose verification
29
- // ---------------------------------------------------------------------------
30
-
31
- const toPublicJwk = (jwk: Record<string, unknown>): Record<string, unknown> => {
32
- const { d, dp, dq, p, q, qi, k, ...publicParts } = jwk as any;
33
- return publicParts;
34
- };
35
-
36
- // ---------------------------------------------------------------------------
37
- // jose JWT interop
38
- // ---------------------------------------------------------------------------
39
-
40
- describe("JWT interop: aegis <-> jose", () => {
41
- describe.each([
42
- { name: "EC / ES256", createKey: createEcSigKey, asymmetric: true },
43
- { name: "RSA / RS256", createKey: createRsaSigKey, asymmetric: true },
44
- { name: "oct / HS256", createKey: createOctSigKey, asymmetric: false },
45
- ])("$name", ({ createKey, asymmetric }) => {
46
- test("aegis sign -> jose verify", async () => {
47
- const kryptos = createKey();
48
- const kit = new JwtKit({ issuer: ISSUER, logger, kryptos });
49
-
50
- const { token } = kit.sign({
51
- expires: "1h",
52
- subject: SUBJECT,
53
- tokenType: "access_token",
54
- });
55
-
56
- // jose needs public key for asymmetric verification, full key for symmetric
57
- const jwk = kryptos.export("jwk");
58
- const verifyJwk = asymmetric ? toPublicJwk(jwk) : jwk;
59
- const joseKey = await importJWK(verifyJwk, jwk.alg);
60
-
61
- const result = await jwtVerify(token, joseKey);
62
-
63
- expect(result.payload.iss).toBe(ISSUER);
64
- expect(result.payload.sub).toBe(SUBJECT);
65
- expect(result.protectedHeader.typ).toBe("at+jwt");
66
- expect(result.payload.exp).toBeDefined();
67
- });
68
-
69
- test("jose sign -> aegis verify", async () => {
70
- const kryptos = createKey();
71
- const kit = new JwtKit({ issuer: ISSUER, logger, kryptos });
72
-
73
- // jose needs private key for signing
74
- const jwk = kryptos.export("jwk");
75
- const joseKey = await importJWK(jwk, jwk.alg);
76
-
77
- const token = await new SignJWT({})
78
- .setProtectedHeader({ alg: jwk.alg, typ: "at+jwt" })
79
- .setIssuer(ISSUER)
80
- .setSubject(SUBJECT)
81
- .setExpirationTime("1h")
82
- .setIssuedAt()
83
- .sign(joseKey);
84
-
85
- const result = kit.verify(token);
86
-
87
- expect(result.payload.issuer).toBe(ISSUER);
88
- expect(result.payload.subject).toBe(SUBJECT);
89
- expect(result.header.tokenType).toBe("access_token");
90
- expect(result.payload.expiresAt).toBeInstanceOf(Date);
91
- });
92
- });
93
- });
94
-
95
- // ---------------------------------------------------------------------------
96
- // jsonwebtoken JWT interop
97
- // ---------------------------------------------------------------------------
98
-
99
- describe("JWT interop: aegis <-> jsonwebtoken", () => {
100
- describe("RS256", () => {
101
- test("aegis sign -> jsonwebtoken verify", () => {
102
- const kryptos = createRsaSigKey();
103
- const kit = new JwtKit({ issuer: ISSUER, logger, kryptos });
104
-
105
- const { token } = kit.sign({
106
- expires: "1h",
107
- subject: SUBJECT,
108
- tokenType: "access_token",
109
- });
110
-
111
- const { publicKey } = kryptos.export("pem");
112
- const result = jsonwebtoken.verify(token, publicKey!) as JwtPayload;
113
-
114
- expect(result.iss).toBe(ISSUER);
115
- expect(result.sub).toBe(SUBJECT);
116
- // token_type is no longer a claim; jsonwebtoken verify doesn't expose header
117
- expect(jsonwebtoken.decode(token, { complete: true })?.header.typ).toBe("at+jwt");
118
- expect(result.exp).toBeDefined();
119
- });
120
-
121
- test("jsonwebtoken sign -> aegis verify", () => {
122
- const kryptos = createRsaSigKey();
123
- const kit = new JwtKit({ issuer: ISSUER, logger, kryptos });
124
-
125
- const { privateKey } = kryptos.export("pem");
126
-
127
- const token = jsonwebtoken.sign({}, privateKey!, {
128
- algorithm: "RS256",
129
- expiresIn: "1h",
130
- header: { alg: "RS256", typ: "at+jwt" },
131
- issuer: ISSUER,
132
- subject: SUBJECT,
133
- });
134
-
135
- const result = kit.verify(token);
136
-
137
- expect(result.payload.issuer).toBe(ISSUER);
138
- expect(result.payload.subject).toBe(SUBJECT);
139
- expect(result.header.tokenType).toBe("access_token");
140
- });
141
- });
142
-
143
- describe("HS256", () => {
144
- test("aegis sign -> jsonwebtoken verify", () => {
145
- const kryptos = createOctSigKey();
146
- const kit = new JwtKit({ issuer: ISSUER, logger, kryptos });
147
-
148
- const { token } = kit.sign({
149
- expires: "1h",
150
- subject: SUBJECT,
151
- tokenType: "access_token",
152
- });
153
-
154
- const { privateKey } = kryptos.export("der");
155
- const result = jsonwebtoken.verify(token, privateKey!) as JwtPayload;
156
-
157
- expect(result.iss).toBe(ISSUER);
158
- expect(result.sub).toBe(SUBJECT);
159
- expect(jsonwebtoken.decode(token, { complete: true })?.header.typ).toBe("at+jwt");
160
- });
161
-
162
- test("jsonwebtoken sign -> aegis verify", () => {
163
- const kryptos = createOctSigKey();
164
- const kit = new JwtKit({ issuer: ISSUER, logger, kryptos });
165
-
166
- const { privateKey } = kryptos.export("der");
167
-
168
- const token = jsonwebtoken.sign({}, privateKey!, {
169
- algorithm: "HS256",
170
- expiresIn: "1h",
171
- header: { alg: "HS256", typ: "at+jwt" },
172
- issuer: ISSUER,
173
- subject: SUBJECT,
174
- });
175
-
176
- const result = kit.verify(token);
177
-
178
- expect(result.payload.issuer).toBe(ISSUER);
179
- expect(result.payload.subject).toBe(SUBJECT);
180
- expect(result.header.tokenType).toBe("access_token");
181
- });
182
- });
183
- });
package/vitest.config.mjs DELETED
@@ -1,6 +0,0 @@
1
- import { createVitestConfig } from "../../vitest.config.base.mjs";
2
-
3
- const config = createVitestConfig();
4
- config.test.include = ["src/**/*.test.ts", "__tests__/**/*.test.ts"];
5
-
6
- export default config;