@oxy.so/core 1.2.1 → 1.3.1

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.
Files changed (100) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/crypto/identityMove.js +123 -0
  3. package/dist/cjs/crypto/keyManager.js +60 -21
  4. package/dist/cjs/crypto/webIdentityCarrier.js +262 -0
  5. package/dist/cjs/i18n/locales/ar-SA.json +16 -13
  6. package/dist/cjs/i18n/locales/ca-ES.json +16 -13
  7. package/dist/cjs/i18n/locales/de-DE.json +16 -13
  8. package/dist/cjs/i18n/locales/en-US.json +16 -17
  9. package/dist/cjs/i18n/locales/es-ES.json +16 -17
  10. package/dist/cjs/i18n/locales/fr-FR.json +16 -13
  11. package/dist/cjs/i18n/locales/it-IT.json +16 -13
  12. package/dist/cjs/i18n/locales/ja-JP.json +16 -13
  13. package/dist/cjs/i18n/locales/ko-KR.json +16 -13
  14. package/dist/cjs/i18n/locales/locales/ar-SA.json +16 -13
  15. package/dist/cjs/i18n/locales/locales/ca-ES.json +16 -13
  16. package/dist/cjs/i18n/locales/locales/de-DE.json +16 -13
  17. package/dist/cjs/i18n/locales/locales/en-US.json +16 -17
  18. package/dist/cjs/i18n/locales/locales/es-ES.json +16 -17
  19. package/dist/cjs/i18n/locales/locales/fr-FR.json +16 -13
  20. package/dist/cjs/i18n/locales/locales/it-IT.json +16 -13
  21. package/dist/cjs/i18n/locales/locales/ja-JP.json +16 -13
  22. package/dist/cjs/i18n/locales/locales/ko-KR.json +16 -13
  23. package/dist/cjs/i18n/locales/locales/pt-PT.json +16 -13
  24. package/dist/cjs/i18n/locales/locales/zh-CN.json +16 -13
  25. package/dist/cjs/i18n/locales/pt-PT.json +16 -13
  26. package/dist/cjs/i18n/locales/zh-CN.json +16 -13
  27. package/dist/cjs/index.js +38 -4
  28. package/dist/cjs/mixins/OxyServices.auth.js +14 -4
  29. package/dist/cjs/mixins/OxyServices.identity.js +14 -0
  30. package/dist/cjs/session/accountDialogController.js +333 -142
  31. package/dist/cjs/utils/authWebUrl.js +8 -1
  32. package/dist/esm/.tsbuildinfo +1 -1
  33. package/dist/esm/crypto/identityMove.js +110 -0
  34. package/dist/esm/crypto/keyManager.js +60 -21
  35. package/dist/esm/crypto/webIdentityCarrier.js +243 -0
  36. package/dist/esm/i18n/locales/ar-SA.json +16 -13
  37. package/dist/esm/i18n/locales/ca-ES.json +16 -13
  38. package/dist/esm/i18n/locales/de-DE.json +16 -13
  39. package/dist/esm/i18n/locales/en-US.json +16 -17
  40. package/dist/esm/i18n/locales/es-ES.json +16 -17
  41. package/dist/esm/i18n/locales/fr-FR.json +16 -13
  42. package/dist/esm/i18n/locales/it-IT.json +16 -13
  43. package/dist/esm/i18n/locales/ja-JP.json +16 -13
  44. package/dist/esm/i18n/locales/ko-KR.json +16 -13
  45. package/dist/esm/i18n/locales/locales/ar-SA.json +16 -13
  46. package/dist/esm/i18n/locales/locales/ca-ES.json +16 -13
  47. package/dist/esm/i18n/locales/locales/de-DE.json +16 -13
  48. package/dist/esm/i18n/locales/locales/en-US.json +16 -17
  49. package/dist/esm/i18n/locales/locales/es-ES.json +16 -17
  50. package/dist/esm/i18n/locales/locales/fr-FR.json +16 -13
  51. package/dist/esm/i18n/locales/locales/it-IT.json +16 -13
  52. package/dist/esm/i18n/locales/locales/ja-JP.json +16 -13
  53. package/dist/esm/i18n/locales/locales/ko-KR.json +16 -13
  54. package/dist/esm/i18n/locales/locales/pt-PT.json +16 -13
  55. package/dist/esm/i18n/locales/locales/zh-CN.json +16 -13
  56. package/dist/esm/i18n/locales/pt-PT.json +16 -13
  57. package/dist/esm/i18n/locales/zh-CN.json +16 -13
  58. package/dist/esm/index.js +5 -1
  59. package/dist/esm/mixins/OxyServices.auth.js +14 -4
  60. package/dist/esm/mixins/OxyServices.identity.js +14 -0
  61. package/dist/esm/session/accountDialogController.js +334 -143
  62. package/dist/esm/utils/authWebUrl.js +7 -0
  63. package/dist/types/.tsbuildinfo +1 -1
  64. package/dist/types/crypto/identityMove.d.ts +59 -0
  65. package/dist/types/crypto/keyManager.d.ts +35 -5
  66. package/dist/types/crypto/webIdentityCarrier.d.ts +123 -0
  67. package/dist/types/index.d.ts +5 -2
  68. package/dist/types/mixins/OxyServices.auth.d.ts +12 -0
  69. package/dist/types/models/interfaces.d.ts +15 -0
  70. package/dist/types/session/accountDialogController.d.ts +169 -17
  71. package/dist/types/utils/authWebUrl.d.ts +7 -0
  72. package/package.json +3 -3
  73. package/src/crypto/__tests__/identityMove.test.ts +104 -0
  74. package/src/crypto/__tests__/keyManager.sharedSlotSync.test.ts +150 -0
  75. package/src/crypto/__tests__/webIdentityCarrier.test.ts +211 -0
  76. package/src/crypto/identityMove.ts +133 -0
  77. package/src/crypto/keyManager.ts +71 -21
  78. package/src/crypto/webIdentityCarrier.ts +326 -0
  79. package/src/i18n/locales/ar-SA.json +16 -13
  80. package/src/i18n/locales/ca-ES.json +16 -13
  81. package/src/i18n/locales/de-DE.json +16 -13
  82. package/src/i18n/locales/en-US.json +16 -17
  83. package/src/i18n/locales/es-ES.json +16 -17
  84. package/src/i18n/locales/fr-FR.json +16 -13
  85. package/src/i18n/locales/it-IT.json +16 -13
  86. package/src/i18n/locales/ja-JP.json +16 -13
  87. package/src/i18n/locales/ko-KR.json +16 -13
  88. package/src/i18n/locales/pt-PT.json +16 -13
  89. package/src/i18n/locales/zh-CN.json +16 -13
  90. package/src/index.ts +38 -1
  91. package/src/mixins/OxyServices.auth.ts +16 -3
  92. package/src/mixins/OxyServices.identity.ts +14 -0
  93. package/src/mixins/__tests__/OxyServices.rotateKey.test.ts +47 -0
  94. package/src/mixins/__tests__/commonsSignIn.test.ts +3 -0
  95. package/src/mixins/__tests__/verifyChallenge.test.ts +31 -0
  96. package/src/models/interfaces.ts +15 -0
  97. package/src/session/__tests__/accountDialogController.test.ts +407 -10
  98. package/src/session/accountDialogController.ts +406 -145
  99. package/src/utils/__tests__/oauthPkce.test.ts +50 -26
  100. package/src/utils/authWebUrl.ts +8 -0
@@ -24,6 +24,24 @@ function nodeCodeChallenge(verifier: string): string {
24
24
  return createHash('sha256').update(verifier).digest('base64url');
25
25
  }
26
26
 
27
+ /**
28
+ * Remove the `sessionStorage` a test installed, so the next test starts without
29
+ * one. When Jest runs on the Bun runtime deleting a global reports success
30
+ * but leaves the property in place, and a later "no sessionStorage" test would
31
+ * then run against a leftover store — so a surviving property is overwritten
32
+ * with `undefined`, which is exactly the absence the code under test checks for.
33
+ */
34
+ function removeSessionStorage(): void {
35
+ Reflect.deleteProperty(globalThis, 'sessionStorage');
36
+ if ((globalThis as { sessionStorage?: Storage }).sessionStorage !== undefined) {
37
+ Object.defineProperty(globalThis, 'sessionStorage', {
38
+ value: undefined,
39
+ configurable: true,
40
+ writable: true,
41
+ });
42
+ }
43
+ }
44
+
27
45
  describe('computeCodeChallenge', () => {
28
46
  it('matches the RFC 7636 Appendix B known-answer vector', async () => {
29
47
  // From RFC 7636 §Appendix B: verifier -> S256 challenge.
@@ -176,22 +194,25 @@ describe('canonicalizeOAuthRedirectUri', () => {
176
194
  describe('OAuth handshake persistence', () => {
177
195
  function installSessionStorage(): Map<string, string> {
178
196
  const map = new Map<string, string>();
179
- (globalThis as { sessionStorage?: Storage }).sessionStorage = {
180
- getItem: (k: string) => (map.has(k) ? (map.get(k) as string) : null),
181
- setItem: (k: string, v: string) => void map.set(k, v),
182
- removeItem: (k: string) => void map.delete(k),
183
- clear: () => map.clear(),
184
- key: (i: number) => [...map.keys()][i] ?? null,
185
- get length() {
186
- return map.size;
187
- },
188
- } as unknown as Storage;
197
+ // Configurable, so `removeSessionStorage` can always take it away again.
198
+ Object.defineProperty(globalThis, 'sessionStorage', {
199
+ value: {
200
+ getItem: (k: string) => (map.has(k) ? (map.get(k) as string) : null),
201
+ setItem: (k: string, v: string) => void map.set(k, v),
202
+ removeItem: (k: string) => void map.delete(k),
203
+ clear: () => map.clear(),
204
+ key: (i: number) => [...map.keys()][i] ?? null,
205
+ get length() {
206
+ return map.size;
207
+ },
208
+ } as unknown as Storage,
209
+ configurable: true,
210
+ writable: true,
211
+ });
189
212
  return map;
190
213
  }
191
214
 
192
- afterEach(() => {
193
- delete (globalThis as { sessionStorage?: Storage }).sessionStorage;
194
- });
215
+ afterEach(removeSessionStorage);
195
216
 
196
217
  it('round-trips redirect_uri through persist/read/clear', () => {
197
218
  const store = installSessionStorage();
@@ -212,22 +233,25 @@ describe('OAuth return path', () => {
212
233
  /** Minimal sessionStorage stand-in — jsdom is not assumed by this suite. */
213
234
  function installSessionStorage(): Map<string, string> {
214
235
  const map = new Map<string, string>();
215
- (globalThis as { sessionStorage?: Storage }).sessionStorage = {
216
- getItem: (k: string) => (map.has(k) ? (map.get(k) as string) : null),
217
- setItem: (k: string, v: string) => void map.set(k, v),
218
- removeItem: (k: string) => void map.delete(k),
219
- clear: () => map.clear(),
220
- key: (i: number) => [...map.keys()][i] ?? null,
221
- get length() {
222
- return map.size;
223
- },
224
- } as unknown as Storage;
236
+ // Configurable, so `removeSessionStorage` can always take it away again.
237
+ Object.defineProperty(globalThis, 'sessionStorage', {
238
+ value: {
239
+ getItem: (k: string) => (map.has(k) ? (map.get(k) as string) : null),
240
+ setItem: (k: string, v: string) => void map.set(k, v),
241
+ removeItem: (k: string) => void map.delete(k),
242
+ clear: () => map.clear(),
243
+ key: (i: number) => [...map.keys()][i] ?? null,
244
+ get length() {
245
+ return map.size;
246
+ },
247
+ } as unknown as Storage,
248
+ configurable: true,
249
+ writable: true,
250
+ });
225
251
  return map;
226
252
  }
227
253
 
228
- afterEach(() => {
229
- delete (globalThis as { sessionStorage?: Storage }).sessionStorage;
230
- });
254
+ afterEach(removeSessionStorage);
231
255
 
232
256
  it('round-trips a deep path through persist/consume', () => {
233
257
  installSessionStorage();
@@ -15,3 +15,11 @@
15
15
  * the CORS helper (and anything else that needs the central apex) never drifts.
16
16
  */
17
17
  export const CENTRAL_IDP_APEX = 'oxy.so';
18
+
19
+ /**
20
+ * The web identity carrier's origin — where a person signs in or creates an
21
+ * account with a passkey, and where their self-custody identity is kept sealed
22
+ * under that passkey (one identity, two carriers). Apps open it; they never
23
+ * handle the identity themselves.
24
+ */
25
+ export const IDENTITY_WEB_ORIGIN = `https://id.${CENTRAL_IDP_APEX}`;