@oxyhq/core 4.0.0 → 5.0.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.
Files changed (119) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/HttpService.js +6 -18
  3. package/dist/cjs/OxyServices.base.js +0 -21
  4. package/dist/cjs/crypto/keyManager.js +7 -7
  5. package/dist/cjs/crypto/polyfill.js +6 -5
  6. package/dist/cjs/crypto/signatureService.js +44 -220
  7. package/dist/cjs/i18n/locales/en-US.json +391 -17
  8. package/dist/cjs/i18n/locales/es-ES.json +391 -17
  9. package/dist/cjs/i18n/locales/locales/en-US.json +391 -17
  10. package/dist/cjs/i18n/locales/locales/es-ES.json +391 -17
  11. package/dist/cjs/index.js +4 -8
  12. package/dist/cjs/mixins/OxyServices.accounts.js +54 -0
  13. package/dist/cjs/mixins/OxyServices.assets.js +2 -2
  14. package/dist/cjs/mixins/OxyServices.auth.js +3 -3
  15. package/dist/cjs/mixins/OxyServices.civic.js +3 -3
  16. package/dist/cjs/mixins/OxyServices.language.js +2 -2
  17. package/dist/cjs/mixins/OxyServices.utility.js +7 -95
  18. package/dist/cjs/utils/cacheKey.js +17 -19
  19. package/dist/cjs/utils/deviceManager.js +2 -2
  20. package/dist/cjs/utils/platform.js +0 -14
  21. package/dist/esm/.tsbuildinfo +1 -1
  22. package/dist/esm/HttpService.js +6 -18
  23. package/dist/esm/OxyServices.base.js +0 -21
  24. package/dist/esm/crypto/keyManager.js +4 -4
  25. package/dist/esm/crypto/polyfill.js +5 -4
  26. package/dist/esm/crypto/signatureService.js +39 -214
  27. package/dist/esm/i18n/locales/en-US.json +391 -17
  28. package/dist/esm/i18n/locales/es-ES.json +391 -17
  29. package/dist/esm/i18n/locales/locales/en-US.json +391 -17
  30. package/dist/esm/i18n/locales/locales/es-ES.json +391 -17
  31. package/dist/esm/index.js +1 -2
  32. package/dist/esm/mixins/OxyServices.accounts.js +54 -0
  33. package/dist/esm/mixins/OxyServices.assets.js +1 -1
  34. package/dist/esm/mixins/OxyServices.auth.js +1 -1
  35. package/dist/esm/mixins/OxyServices.civic.js +3 -3
  36. package/dist/esm/mixins/OxyServices.language.js +1 -1
  37. package/dist/esm/mixins/OxyServices.utility.js +6 -94
  38. package/dist/esm/utils/cacheKey.js +17 -19
  39. package/dist/esm/utils/deviceManager.js +1 -1
  40. package/dist/esm/utils/platform.js +0 -12
  41. package/dist/types/.tsbuildinfo +1 -1
  42. package/dist/types/HttpService.d.ts +3 -6
  43. package/dist/types/OxyServices.base.d.ts +0 -17
  44. package/dist/types/crypto/polyfill.d.ts +2 -2
  45. package/dist/types/crypto/signatureService.d.ts +18 -84
  46. package/dist/types/index.d.ts +3 -4
  47. package/dist/types/mixins/OxyServices.accounts.d.ts +57 -5
  48. package/dist/types/mixins/OxyServices.analytics.d.ts +0 -2
  49. package/dist/types/mixins/OxyServices.appData.d.ts +0 -2
  50. package/dist/types/mixins/OxyServices.assets.d.ts +0 -2
  51. package/dist/types/mixins/OxyServices.auth.d.ts +0 -2
  52. package/dist/types/mixins/OxyServices.civic.d.ts +3 -5
  53. package/dist/types/mixins/OxyServices.connectedApps.d.ts +0 -2
  54. package/dist/types/mixins/OxyServices.contacts.d.ts +0 -2
  55. package/dist/types/mixins/OxyServices.devices.d.ts +0 -2
  56. package/dist/types/mixins/OxyServices.features.d.ts +0 -2
  57. package/dist/types/mixins/OxyServices.fedcm.d.ts +0 -2
  58. package/dist/types/mixins/OxyServices.identity.d.ts +8 -5
  59. package/dist/types/mixins/OxyServices.language.d.ts +0 -2
  60. package/dist/types/mixins/OxyServices.links.d.ts +0 -2
  61. package/dist/types/mixins/OxyServices.location.d.ts +0 -2
  62. package/dist/types/mixins/OxyServices.nodes.d.ts +0 -44
  63. package/dist/types/mixins/OxyServices.payment.d.ts +0 -2
  64. package/dist/types/mixins/OxyServices.privacy.d.ts +0 -2
  65. package/dist/types/mixins/OxyServices.redirect.d.ts +0 -2
  66. package/dist/types/mixins/OxyServices.reputation.d.ts +0 -2
  67. package/dist/types/mixins/OxyServices.security.d.ts +0 -2
  68. package/dist/types/mixins/OxyServices.silent.d.ts +0 -2
  69. package/dist/types/mixins/OxyServices.sso.d.ts +0 -2
  70. package/dist/types/mixins/OxyServices.topics.d.ts +0 -2
  71. package/dist/types/mixins/OxyServices.user.d.ts +0 -2
  72. package/dist/types/mixins/OxyServices.utility.d.ts +0 -32
  73. package/dist/types/server/auth.d.ts +0 -6
  74. package/dist/types/server/index.d.ts +1 -1
  75. package/dist/types/utils/cacheKey.d.ts +6 -7
  76. package/dist/types/utils/platform.d.ts +0 -8
  77. package/package.json +4 -7
  78. package/src/HttpService.ts +6 -22
  79. package/src/OxyServices.base.ts +0 -23
  80. package/src/__tests__/httpServiceCache.test.ts +0 -19
  81. package/src/crypto/__tests__/keyManager.atomicity.test.ts +2 -1
  82. package/src/crypto/__tests__/keyManager.test.ts +9 -7
  83. package/src/crypto/__tests__/signChallengeShared.test.ts +2 -1
  84. package/src/crypto/__tests__/signedRecord.test.ts +37 -150
  85. package/src/crypto/keyManager.ts +28 -17
  86. package/src/crypto/polyfill.ts +5 -4
  87. package/src/crypto/signatureService.ts +67 -255
  88. package/src/i18n/locales/en-US.json +391 -17
  89. package/src/i18n/locales/es-ES.json +391 -17
  90. package/src/index.ts +3 -3
  91. package/src/mixins/OxyServices.accounts.ts +91 -3
  92. package/src/mixins/OxyServices.assets.ts +1 -1
  93. package/src/mixins/OxyServices.auth.ts +1 -1
  94. package/src/mixins/OxyServices.civic.ts +6 -17
  95. package/src/mixins/OxyServices.identity.ts +8 -2
  96. package/src/mixins/OxyServices.language.ts +1 -1
  97. package/src/mixins/OxyServices.nodes.ts +1 -12
  98. package/src/mixins/OxyServices.utility.ts +6 -119
  99. package/src/mixins/__tests__/OxyServices.civic.test.ts +2 -2
  100. package/src/mixins/__tests__/accounts.test.ts +70 -0
  101. package/src/server/auth.ts +0 -7
  102. package/src/server/index.ts +0 -1
  103. package/src/utils/__tests__/cacheKey.test.ts +0 -0
  104. package/src/utils/cacheKey.ts +16 -21
  105. package/src/utils/deviceManager.ts +1 -1
  106. package/src/utils/platform.ts +0 -14
  107. package/dist/cjs/crypto/canonicalJson.js +0 -107
  108. package/dist/cjs/utils/platformCrypto.js +0 -165
  109. package/dist/cjs/utils/platformCrypto.native.js +0 -123
  110. package/dist/esm/crypto/canonicalJson.js +0 -104
  111. package/dist/esm/utils/platformCrypto.js +0 -125
  112. package/dist/esm/utils/platformCrypto.native.js +0 -80
  113. package/dist/types/crypto/canonicalJson.d.ts +0 -44
  114. package/dist/types/utils/platformCrypto.d.ts +0 -87
  115. package/dist/types/utils/platformCrypto.native.d.ts +0 -54
  116. package/src/crypto/__tests__/canonicalJson.test.ts +0 -116
  117. package/src/crypto/canonicalJson.ts +0 -120
  118. package/src/utils/platformCrypto.native.ts +0 -101
  119. package/src/utils/platformCrypto.ts +0 -145
@@ -110,7 +110,9 @@
110
110
  "reputation": "Reputación",
111
111
  "followers": "Seguidores",
112
112
  "following": "Siguiendo",
113
- "more": "+ {{count}} más"
113
+ "more": "+ {{count}} más",
114
+ "errorTitle": "Error de perfil",
115
+ "errorSubtext": "Esto puede ocurrir si el usuario no existe o el servicio de perfiles no está disponible."
114
116
  },
115
117
  "language": {
116
118
  "title": "Idioma",
@@ -118,7 +120,8 @@
118
120
  "current": "Idioma actual",
119
121
  "available": "Idiomas disponibles",
120
122
  "changed": "Idioma cambiado a {{lang}}",
121
- "saveFailed": "Error al guardar la preferencia de idioma"
123
+ "saveFailed": "Error al guardar la preferencia de idioma",
124
+ "search": "Buscar idiomas"
122
125
  },
123
126
  "recover": {
124
127
  "title": "Recuperar cuenta",
@@ -269,7 +272,8 @@
269
272
  "cropMeasureFailed": "No se pudo medir la imagen",
270
273
  "cropNotReady": "La imagen aún no está lista",
271
274
  "cropFailed": "No se pudo recortar la imagen"
272
- }
275
+ },
276
+ "changeAvatar": "Cambiar avatar"
273
277
  },
274
278
  "common": {
275
279
  "actions": {
@@ -283,7 +287,8 @@
283
287
  "verify": "Verificar",
284
288
  "resetPassword": "Restablecer contraseña",
285
289
  "signedOut": "Sesión cerrada",
286
- "close": "Cerrar"
290
+ "close": "Cerrar",
291
+ "delete": "Eliminar"
287
292
  },
288
293
  "cancel": "Cancelar",
289
294
  "revoke": "Revocar",
@@ -314,7 +319,9 @@
314
319
  "status": {
315
320
  "notSignedIn": "No has iniciado sesión",
316
321
  "loading": "Cargando..."
317
- }
322
+ },
323
+ "back": "Atrás",
324
+ "remove": "Eliminar"
318
325
  },
319
326
  "accountOverview": {
320
327
  "title": "Cuenta",
@@ -459,7 +466,8 @@
459
466
  "accountManagement": "Gestión de la cuenta",
460
467
  "multiAccount": "Multi‑cuenta",
461
468
  "addAccount": "Añadir cuenta",
462
- "moreOptions": "Más opciones"
469
+ "moreOptions": "Más opciones",
470
+ "accounts": "Cuentas"
463
471
  },
464
472
  "quickActions": {
465
473
  "overview": "Resumen",
@@ -521,7 +529,10 @@
521
529
  "sections": {
522
530
  "current": "Cuenta actual",
523
531
  "otherWithCount": "Otras cuentas ({{count}})",
524
- "deviceSessions": "Sesiones de dispositivo"
532
+ "deviceSessions": "Sesiones de dispositivo",
533
+ "sharedWithYou": "Compartidas contigo",
534
+ "thisDevice": "En este dispositivo",
535
+ "yourAccounts": "Tus cuentas"
525
536
  },
526
537
  "currentBadge": "Actual",
527
538
  "loading": "Cargando cuentas...",
@@ -556,7 +567,9 @@
556
567
  "empty": {
557
568
  "title": "No hay cuentas guardadas",
558
569
  "subtitle": "Añade otra cuenta para cambiar rápidamente entre ellas"
559
- }
570
+ },
571
+ "label": "Selector de cuentas",
572
+ "searchPlaceholder": "Buscar cuentas"
560
573
  },
561
574
  "feedback": {
562
575
  "type": {
@@ -599,7 +612,8 @@
599
612
  "priority": "Prioridad:",
600
613
  "category": "Categoría:",
601
614
  "titleLabel": "Título:",
602
- "contact": "Contacto:"
615
+ "contact": "Contacto:",
616
+ "titleField": "Título:"
603
617
  },
604
618
  "actions": {
605
619
  "submit": "Enviar comentario",
@@ -614,7 +628,9 @@
614
628
  "thanks": "¡Gracias por tu comentario!",
615
629
  "submitFailed": "Error al enviar el comentario",
616
630
  "submitSuccess": "¡Comentario enviado correctamente!"
617
- }
631
+ },
632
+ "title": "Comentarios",
633
+ "subtitle": "Cuéntanos qué opinas"
618
634
  },
619
635
  "reputation": {
620
636
  "faq": {
@@ -775,7 +791,9 @@
775
791
  },
776
792
  "confirms": {
777
793
  "cancelSub": "¿Seguro que quieres cancelar tu suscripción? Perderás el acceso a las funciones premium al final del periodo de facturación.",
778
- "unsubscribeFeature": "¿Seguro que quieres darte de baja de {{name}}?"
794
+ "unsubscribeFeature": "¿Seguro que quieres darte de baja de {{name}}?",
795
+ "cancelSubTitle": "Cancelar suscripción",
796
+ "unsubscribeFeatureTitle": "Cancelar suscripción a la función"
779
797
  },
780
798
  "current": {
781
799
  "title": "Suscripción actual",
@@ -793,11 +811,13 @@
793
811
  "billing": {
794
812
  "monthly": "Mensual",
795
813
  "yearly": "Anual",
796
- "saveYearly": "💰 Ahorra un 20% con la facturación anual"
814
+ "saveYearly": "💰 Ahorra un 20% con la facturación anual",
815
+ "label": "Periodo de facturación"
797
816
  },
798
817
  "tabs": {
799
818
  "plans": "Planes completos",
800
- "features": "Funciones individuales"
819
+ "features": "Funciones individuales",
820
+ "label": "Tipo de suscripción"
801
821
  },
802
822
  "plan": {
803
823
  "scope": {
@@ -807,7 +827,8 @@
807
827
  },
808
828
  "badge": {
809
829
  "appExclusive": "Exclusivo de la app",
810
- "notAvailable": "No disponible"
830
+ "notAvailable": "No disponible",
831
+ "mostPopular": "Más popular"
811
832
  },
812
833
  "perInterval": "por {{interval}}",
813
834
  "current": "Plan actual",
@@ -819,7 +840,16 @@
819
840
  "availableIn": "Disponible en: {{apps}}"
820
841
  },
821
842
  "includedInPlan": "Incluido en tu plan",
822
- "subscribed": "Suscrito"
843
+ "subscribed": "Suscrito",
844
+ "included": "Incluido",
845
+ "plansOnly": "Solo disponible en los planes de suscripción"
846
+ },
847
+ "features": {
848
+ "title": "Funciones individuales",
849
+ "subtitle": "Suscríbete a las funciones concretas que necesitas. Algunas funciones están incluidas en los planes de suscripción."
850
+ },
851
+ "dev": {
852
+ "appContext": "Contexto de app de prueba (solo desarrollo)"
823
853
  }
824
854
  },
825
855
  "welcomeNew": {
@@ -874,6 +904,10 @@
874
904
  "skip": "Omitir",
875
905
  "enter": "Entrar",
876
906
  "continue": "Continuar"
907
+ },
908
+ "trust": {
909
+ "title": "Oxy Trust = Confianza y crecimiento",
910
+ "body": "Oxy Trust es un sistema de reputación que reacciona a lo que haces. Las acciones útiles, respetuosas y constructivas ganan reputación. Lo dañino o de poco esfuerzo la reduce. Más reputación eleva tu nivel de confianza y puede desbloquear beneficios; una reputación baja puede limitar funciones. Mantiene las cosas justas y recompensa la contribución real."
877
911
  }
878
912
  },
879
913
  "history": {
@@ -929,6 +963,9 @@
929
963
  "description": "Usa tu actividad para mejorar los resultados de búsqueda",
930
964
  "updated": "Personalización de búsqueda actualizada",
931
965
  "error": "Error al actualizar la personalización"
966
+ },
967
+ "searchPersonalization": {
968
+ "error": "No se pudo actualizar la personalización"
932
969
  }
933
970
  },
934
971
  "privacySettings": {
@@ -990,7 +1027,8 @@
990
1027
  "title": "Verificación de cuenta",
991
1028
  "description": "Solicita una insignia verificada para tu cuenta. Las cuentas verificadas ayudan a establecer autenticidad y credibilidad.",
992
1029
  "sections": {
993
- "request": "SOLICITUD DE VERIFICACIÓN"
1030
+ "request": "SOLICITUD DE VERIFICACIÓN",
1031
+ "benefits": "Qué te aporta la verificación"
994
1032
  },
995
1033
  "reasonLabel": "Motivo de la verificación *",
996
1034
  "reasonPlaceholder": "Explica por qué necesitas una insignia verificada (p. ej., figura pública, marca, organización)",
@@ -1003,7 +1041,13 @@
1003
1041
  "successMessage": "Tu solicitud de verificación ha sido enviada. ID de solicitud: {{requestId}}",
1004
1042
  "ok": "OK",
1005
1043
  "error": "Servicio no disponible",
1006
- "note": "Nota: Las solicitudes de verificación se revisan manualmente y pueden tardar varios días. Te notificaremos cuando tu solicitud haya sido revisada."
1044
+ "note": "Nota: Las solicitudes de verificación se revisan manualmente y pueden tardar varios días. Te notificaremos cuando tu solicitud haya sido revisada.",
1045
+ "heroTitle": "Consigue una insignia de verificación",
1046
+ "benefits": {
1047
+ "authenticity": "Confirma que tu identidad es auténtica y de confianza",
1048
+ "badge": "Muestra una insignia de verificación en toda la plataforma",
1049
+ "credibility": "Genera credibilidad ante quienes te siguen"
1050
+ }
1007
1051
  },
1008
1052
  "help": {
1009
1053
  "title": "Ayuda y soporte",
@@ -1518,5 +1562,335 @@
1518
1562
  "openWithUser": "Menú de cuenta de {{name}}",
1519
1563
  "switching": "Cambiando de cuenta…",
1520
1564
  "signOutAccount": "Cerrar sesión de {{name}}"
1565
+ },
1566
+ "accounts": {
1567
+ "activeAccount": {
1568
+ "a11y": "Cuenta activa: {{name}}. Toca para cambiar de cuenta.",
1569
+ "label": "Cuenta activa"
1570
+ },
1571
+ "roles": {
1572
+ "owner": {
1573
+ "label": "Propietario"
1574
+ },
1575
+ "admin": {
1576
+ "label": "Administrador"
1577
+ },
1578
+ "editor": {
1579
+ "label": "Editor"
1580
+ },
1581
+ "developer": {
1582
+ "label": "Desarrollador"
1583
+ },
1584
+ "billing": {
1585
+ "label": "Facturación"
1586
+ },
1587
+ "viewer": {
1588
+ "label": "Lector"
1589
+ }
1590
+ },
1591
+ "kinds": {
1592
+ "organization": {
1593
+ "label": "Organización",
1594
+ "description": "Una cuenta de equipo compartida con miembros"
1595
+ },
1596
+ "project": {
1597
+ "label": "Proyecto",
1598
+ "description": "Una cuenta independiente que tú controlas"
1599
+ },
1600
+ "bot": {
1601
+ "label": "Bot",
1602
+ "description": "Una cuenta programática con credenciales de servicio"
1603
+ }
1604
+ },
1605
+ "create": {
1606
+ "title": "Crear cuenta",
1607
+ "subtitle": "Crea una cuenta que tú controlas. Tendrá su propio perfil, miembros y aplicaciones.",
1608
+ "displayName": {
1609
+ "label": "Nombre visible"
1610
+ },
1611
+ "bio": {
1612
+ "label": "Biografía (opcional)"
1613
+ },
1614
+ "username": {
1615
+ "label": "Nombre de usuario",
1616
+ "available": "El nombre de usuario está disponible",
1617
+ "taken": "El nombre de usuario ya está en uso",
1618
+ "tooShort": "El nombre de usuario debe tener al menos 3 caracteres",
1619
+ "invalidChars": "Solo letras, números, guiones y guiones bajos",
1620
+ "checkFailed": "No se pudo comprobar la disponibilidad"
1621
+ },
1622
+ "toasts": {
1623
+ "success": "Cuenta creada",
1624
+ "failed": "No se pudo crear la cuenta"
1625
+ }
1626
+ },
1627
+ "manage": {
1628
+ "create": {
1629
+ "subtitle": "Añade una organización, proyecto o bot"
1630
+ },
1631
+ "switch": {
1632
+ "title": "Cambiar de cuenta",
1633
+ "count": "{{count}} cuentas",
1634
+ "empty": "Cuentas que posees o compartes"
1635
+ }
1636
+ },
1637
+ "members": {
1638
+ "title": "Miembros",
1639
+ "subtitle": "Personas con acceso a esta cuenta.",
1640
+ "empty": "Aún no hay miembros.",
1641
+ "actions": {
1642
+ "remove": "Eliminar miembro",
1643
+ "transfer": "Transferir propiedad"
1644
+ },
1645
+ "errors": {
1646
+ "identifierRequired": "Introduce un nombre de usuario o correo para invitar",
1647
+ "missingAccount": "Ninguna cuenta seleccionada.",
1648
+ "noPermission": "No tienes permiso para ver los miembros.",
1649
+ "userNotFound": "Usuario no encontrado"
1650
+ },
1651
+ "invite": {
1652
+ "title": "Añadir un miembro",
1653
+ "identifierLabel": "Nombre de usuario o correo",
1654
+ "roleLabel": "Rol",
1655
+ "submit": "Añadir miembro"
1656
+ },
1657
+ "removeConfirm": {
1658
+ "title": "Eliminar miembro",
1659
+ "description": "¿Eliminar a este miembro de la cuenta? Perderá todo el acceso."
1660
+ },
1661
+ "transferConfirm": {
1662
+ "title": "Transferir propiedad",
1663
+ "description": "¿Transferir la propiedad de esta cuenta a este miembro? Pasarás a ser administrador. Esto no se puede deshacer."
1664
+ },
1665
+ "toasts": {
1666
+ "added": "Miembro añadido",
1667
+ "addFailed": "No se pudo añadir el miembro",
1668
+ "removed": "Miembro eliminado",
1669
+ "removeFailed": "No se pudo eliminar el miembro",
1670
+ "roleUpdated": "Rol actualizado",
1671
+ "roleFailed": "No se pudo actualizar el rol",
1672
+ "transferred": "Propiedad transferida",
1673
+ "transferFailed": "No se pudo transferir la propiedad"
1674
+ }
1675
+ },
1676
+ "settings": {
1677
+ "title": "Configuración de la cuenta",
1678
+ "subtitle": "Gestiona el perfil, los miembros y el acceso de esta cuenta.",
1679
+ "save": "Guardar cambios",
1680
+ "displayName": {
1681
+ "label": "Nombre visible"
1682
+ },
1683
+ "bio": {
1684
+ "label": "Biografía (opcional)"
1685
+ },
1686
+ "sections": {
1687
+ "access": "Acceso",
1688
+ "dangerZone": "Zona de peligro"
1689
+ },
1690
+ "members": {
1691
+ "subtitle": "Invita a personas y gestiona los roles"
1692
+ },
1693
+ "archive": {
1694
+ "title": "Archivar cuenta",
1695
+ "subtitle": "Desactivar esta cuenta",
1696
+ "confirmTitle": "Archivar cuenta",
1697
+ "confirmDescription": "¿Archivar esta cuenta? Se desactivará y sus miembros perderán el acceso."
1698
+ },
1699
+ "errors": {
1700
+ "missingAccount": "Ninguna cuenta seleccionada."
1701
+ },
1702
+ "toasts": {
1703
+ "saved": "Cuenta actualizada",
1704
+ "saveFailed": "No se pudo actualizar la cuenta",
1705
+ "archived": "Cuenta archivada",
1706
+ "archiveFailed": "No se pudo archivar la cuenta"
1707
+ }
1708
+ }
1709
+ },
1710
+ "deleteAccount": {
1711
+ "title": "Eliminar cuenta",
1712
+ "warning": "Esta acción no se puede deshacer. Tu cuenta y todos los datos asociados se eliminarán de forma permanente.",
1713
+ "confirmLabel": "Escribe \"{{username}}\" para confirmar",
1714
+ "confirm": "Eliminar para siempre",
1715
+ "error": "No se pudo eliminar la cuenta"
1716
+ },
1717
+ "manageAccount": {
1718
+ "title": "Gestiona tu cuenta de Oxy",
1719
+ "signOutOfThisAccount": "Cerrar sesión de esta cuenta",
1720
+ "sections": {
1721
+ "profile": "Perfil",
1722
+ "preferences": "Preferencias",
1723
+ "security": "Seguridad",
1724
+ "sessions": "Sesiones y dispositivos",
1725
+ "legal": "Legal",
1726
+ "dangerZone": "Zona de peligro"
1727
+ },
1728
+ "items": {
1729
+ "editProfile": {
1730
+ "title": "Editar perfil",
1731
+ "subtitle": "Nombre, usuario, biografía, enlaces"
1732
+ },
1733
+ "theme": {
1734
+ "title": "Color del tema",
1735
+ "subtitle": "Personaliza tu color de Bloom"
1736
+ },
1737
+ "security": {
1738
+ "title": "Configuración de seguridad",
1739
+ "subtitle": "Contraseña, 2FA, recuperación"
1740
+ },
1741
+ "billing": {
1742
+ "title": "Facturación",
1743
+ "subtitle": "Gestiona la suscripción y los métodos de pago"
1744
+ }
1745
+ },
1746
+ "sessions": {
1747
+ "thisDevice": "Este dispositivo",
1748
+ "lastActive": "Última actividad {{relative}}",
1749
+ "loading": "Cargando sesiones…",
1750
+ "empty": "No hay sesiones activas",
1751
+ "signOutAllOnThisDevice": "Cerrar sesión en los demás dispositivos",
1752
+ "signOutAllSubtitle": "Finalizar {{count}} sesión(es) de otros dispositivos"
1753
+ },
1754
+ "confirms": {
1755
+ "removeDeviceTitle": "Eliminar dispositivo",
1756
+ "removeDevice": "¿Cerrar sesión en \"{{name}}\"?",
1757
+ "signOutAllDevicesTitle": "Cerrar sesión en los demás dispositivos",
1758
+ "signOutAllDevices": "¿Finalizar {{count}} sesión(es) de otros dispositivos? No se cerrará tu sesión aquí."
1759
+ },
1760
+ "toasts": {
1761
+ "deviceRemoved": "Sesión cerrada en {{name}}",
1762
+ "deviceRemoveFailed": "No se pudo eliminar el dispositivo",
1763
+ "allDevicesSignedOut": "Sesión cerrada en todos los demás dispositivos",
1764
+ "allDevicesFailed": "No se pudo cerrar sesión en los demás dispositivos"
1765
+ }
1766
+ },
1767
+ "trust": {
1768
+ "tiers": {
1769
+ "new": "Nuevo",
1770
+ "trusted": "De confianza",
1771
+ "high_trust": "Alta confianza",
1772
+ "verified": "Verificado",
1773
+ "restricted": "Restringido"
1774
+ },
1775
+ "center": {
1776
+ "title": "Centro de confianza",
1777
+ "balance": "puntos de reputación",
1778
+ "history": "Historial de reputación",
1779
+ "noHistory": "Aún no hay historial de reputación.",
1780
+ "noDescription": "Sin descripción",
1781
+ "info": "La reputación solo se gana con acciones positivas en el ecosistema Oxy. No se puede enviar ni recibir directamente.",
1782
+ "loadError": "No se pudieron cargar los datos de reputación",
1783
+ "actions": {
1784
+ "title": "Explorar",
1785
+ "about": "Acerca de",
1786
+ "faq": "Preguntas frecuentes",
1787
+ "leaderboard": "Clasificación",
1788
+ "rewards": "Recompensas",
1789
+ "rules": "Reglas"
1790
+ }
1791
+ },
1792
+ "about": {
1793
+ "title": "Acerca de Oxy Trust",
1794
+ "subtitle": "Conoce el sistema de reputación",
1795
+ "intro": "Oxy Trust es un reconocimiento de tus acciones positivas en el ecosistema Oxy. La reputación no se puede enviar ni recibir directamente, solo se gana contribuyendo a la comunidad.",
1796
+ "how": {
1797
+ "title": "Cómo ganar reputación",
1798
+ "contribute": "Aportar contenido",
1799
+ "help": "Ayudar a otros usuarios",
1800
+ "participate": "Participar en eventos",
1801
+ "report": "Reportar errores",
1802
+ "other": "Otras acciones positivas"
1803
+ },
1804
+ "why": {
1805
+ "title": "¿Por qué Oxy Trust?",
1806
+ "text": "Tu reputación y tu nivel de confianza desbloquean funciones especiales y reconocimiento en el ecosistema Oxy. ¡Cuanto más contribuyas, más ganas!"
1807
+ }
1808
+ },
1809
+ "faq": {
1810
+ "title": "Preguntas frecuentes de Trust",
1811
+ "subtitle": "Preguntas frecuentes sobre Oxy Trust",
1812
+ "search": "Buscar preguntas frecuentes...",
1813
+ "noResults": "No se encontraron preguntas que coincidan con \"{{query}}\"",
1814
+ "items": {
1815
+ "what": {
1816
+ "q": "¿Qué es Oxy Trust?",
1817
+ "a": "Oxy Trust es un sistema de reputación que reconoce tus contribuciones positivas en todo el ecosistema Oxy. Tu reputación refleja lo útiles, respetuosas y constructivas que son tus acciones."
1818
+ },
1819
+ "earn": {
1820
+ "q": "¿Cómo gano reputación?",
1821
+ "a": "Ganas reputación aportando contenido, ayudando a otros usuarios, participando en eventos y reportando errores. Las acciones constructivas y positivas elevan tu reputación con el tiempo."
1822
+ },
1823
+ "lose": {
1824
+ "q": "¿Puedo perder reputación?",
1825
+ "a": "Sí. Las acciones dañinas, abusivas o de poco esfuerzo pueden reducir tu reputación y bajar tu nivel de confianza."
1826
+ },
1827
+ "use": {
1828
+ "q": "¿Para qué sirve la reputación?",
1829
+ "a": "Tu reputación y tu nivel de confianza desbloquean funciones especiales, reconocimiento y privilegios en todo el ecosistema Oxy."
1830
+ },
1831
+ "transfer": {
1832
+ "q": "¿Puedo enviar o recibir reputación?",
1833
+ "a": "No. La reputación no se puede transferir entre cuentas. Solo se puede ganar con tus propias acciones."
1834
+ },
1835
+ "support": {
1836
+ "q": "¿Dónde puedo conseguir ayuda?",
1837
+ "a": "Si tienes preguntas sobre Oxy Trust, lee la sección Acerca de o contacta con soporte desde la pantalla de Ayuda."
1838
+ }
1839
+ }
1840
+ },
1841
+ "leaderboard": {
1842
+ "title": "Clasificación de Trust",
1843
+ "subtitle": "Principales colaboradores de la comunidad",
1844
+ "rankLabel": "puesto {{rank}}",
1845
+ "empty": "No hay datos de clasificación",
1846
+ "emptyDesc": "Los principales colaboradores aparecerán aquí a medida que crezca la comunidad.",
1847
+ "error": "No se pudo cargar la clasificación"
1848
+ },
1849
+ "rewards": {
1850
+ "title": "Recompensas de Trust",
1851
+ "subtitle": "Desbloquea funciones especiales y reconocimiento"
1852
+ },
1853
+ "rules": {
1854
+ "title": "Reglas de Trust",
1855
+ "subtitle": "Cómo ganar reputación",
1856
+ "empty": "No se encontraron reglas.",
1857
+ "categories": {
1858
+ "content": "Contenido",
1859
+ "social": "Social",
1860
+ "trust": "Confianza",
1861
+ "moderation": "Moderación",
1862
+ "physical": "Vida real",
1863
+ "penalty": "Penalizaciones",
1864
+ "other": "Otros"
1865
+ }
1866
+ },
1867
+ "achievements": {
1868
+ "unlocked": "Logros",
1869
+ "locked": "Logros bloqueados",
1870
+ "firstStep": "Primer paso",
1871
+ "firstStepDesc": "Ganaste tu primer punto de reputación",
1872
+ "novice": "Principiante",
1873
+ "noviceDesc": "Alcanzaste 10 puntos de reputación",
1874
+ "contributor": "Colaborador",
1875
+ "contributorDesc": "Alcanzaste 50 puntos de reputación",
1876
+ "risingStar": "Estrella emergente",
1877
+ "risingStarDesc": "Alcanzaste 100 puntos de reputación",
1878
+ "communityHero": "Héroe de la comunidad",
1879
+ "communityHeroDesc": "Alcanzaste 500 puntos de reputación",
1880
+ "legend": "Leyenda",
1881
+ "legendDesc": "Alcanzaste 1000 puntos de reputación",
1882
+ "phoenix": "Fénix",
1883
+ "phoenixDesc": "Alcanzaste 2500 puntos de reputación",
1884
+ "unstoppable": "Imparable",
1885
+ "unstoppableDesc": "Alcanzaste 5000 puntos de reputación",
1886
+ "helper": "Ayudante",
1887
+ "helperDesc": "Ayudaste a 10 usuarios",
1888
+ "bugHunter": "Cazador de errores",
1889
+ "bugHunterDesc": "Reportaste errores útiles",
1890
+ "streakMaster": "Maestro de la racha",
1891
+ "streakMasterDesc": "Racha de actividad de 7 días",
1892
+ "earlyAdopter": "Pionero",
1893
+ "earlyAdopterDesc": "Has formado parte de la comunidad desde el principio"
1894
+ }
1521
1895
  }
1522
1896
  }
package/dist/esm/index.js CHANGED
@@ -64,8 +64,7 @@ export { mergeSessions, normalizeAndSortSessions, sessionsArraysEqual, } from '.
64
64
  // Crypto / identity
65
65
  // ---------------------------------------------------------------------------
66
66
  export { KeyManager, IdentityAlreadyExistsError, IdentityPersistError, } from './crypto/keyManager.js';
67
- export { SignatureService, signedRecordSigningInput, computeRecordId } from './crypto/signatureService.js';
68
- export { canonicalize } from './crypto/canonicalJson.js';
67
+ export { SignatureService } from './crypto/signatureService.js';
69
68
  export { RecoveryPhraseService } from './crypto/recoveryPhrase.js';
70
69
  // ---------------------------------------------------------------------------
71
70
  // Devices
@@ -1,3 +1,4 @@
1
+ import { normalizeUserIdentity } from '../utils/userIdentity.js';
1
2
  import { CACHE_TIMES } from './mixinHelpers.js';
2
3
  export function OxyServicesAccountsMixin(Base) {
3
4
  return class extends Base {
@@ -40,6 +41,59 @@ export function OxyServicesAccountsMixin(Base) {
40
41
  throw this.handleError(error);
41
42
  }
42
43
  }
44
+ /**
45
+ * Switch the active session INTO a managed account.
46
+ *
47
+ * Calls `POST /accounts/:id/switch` with the signed-in operator's bearer.
48
+ * The server authorises the operator (must hold `account:act_as` over the
49
+ * target, directly or inherited — else 403; 404 if missing/archived; 403 if
50
+ * the target is a personal account), then mints a REAL session for the
51
+ * target account and returns it in the canonical login / `claimSessionByToken`
52
+ * shape (`{ sessionId, deviceId, expiresAt, accessToken, user, authuser }`).
53
+ *
54
+ * Unlike the removed `X-Acting-As` delegation header, the returned session
55
+ * IS the new identity: this plants `accessToken` as the active token —
56
+ * exactly like `claimSessionByToken` / `verifyChallenge` — so every
57
+ * subsequent request authenticates as the target account. The refresh token
58
+ * is the server-set httpOnly `oxy_rt_<authuser>` cookie (never in the body),
59
+ * so it joins the device multi-account set and survives reload /
60
+ * `refresh-all` with no extra client work.
61
+ *
62
+ * After planting, the SDK's identity-scoped GET cache is fully cleared so
63
+ * every cached read re-fetches as the new account. (The consuming
64
+ * `OxyContext` additionally invalidates its React Query cache and updates
65
+ * session state from the returned `user`; this clears the SDK's own HTTP
66
+ * cache at the source — `setTokens` deliberately preserves the warm cache for
67
+ * same-user silent refreshes, so the sweep here is explicit.)
68
+ *
69
+ * @param accountId - The target account's Mongo `_id`.
70
+ * @returns The minted session (planted) plus the device `authuser` slot.
71
+ */
72
+ async switchToAccount(accountId) {
73
+ try {
74
+ const res = await this.makeRequest('POST', `/accounts/${encodeURIComponent(accountId)}/switch`, undefined, { cache: false });
75
+ // Plant the freshly minted session as the ACTIVE session, mirroring
76
+ // `claimSessionByToken` / `verifyChallenge`: the response body carries
77
+ // the first access token; the refresh token is the server-set httpOnly
78
+ // cookie, so there is nothing else to store here.
79
+ if (res?.accessToken) {
80
+ this.setTokens(res.accessToken);
81
+ }
82
+ // Identity changed → drop the entire GET response cache so no entry
83
+ // personalised for the previous identity is reused. Cache keys are
84
+ // identity-scoped, so a different identity could not READ the old
85
+ // entries anyway, but clearing guarantees a clean refetch as the new
86
+ // account and frees the prior identity's resident data.
87
+ this.clearCache();
88
+ return {
89
+ ...res,
90
+ user: normalizeUserIdentity(res.user),
91
+ };
92
+ }
93
+ catch (error) {
94
+ throw this.handleError(error);
95
+ }
96
+ }
43
97
  /**
44
98
  * Create a new (non-personal) account. The caller becomes its `owner`.
45
99
  * @param data - Account configuration: kind, optional parent, and profile.
@@ -1,4 +1,4 @@
1
- import { isReactNative } from '../utils/platform.js';
1
+ import { isReactNative } from '@oxyhq/protocol';
2
2
  export function OxyServicesAssetsMixin(Base) {
3
3
  return class extends Base {
4
4
  constructor(...args) {
@@ -1,7 +1,7 @@
1
1
  import { OxyAuthenticationError } from '../OxyServices.errors.js';
2
2
  import { KeyManager } from '../crypto/keyManager.js';
3
3
  import { SignatureService } from '../crypto/signatureService.js';
4
- import { loadNodeCrypto } from '../utils/platformCrypto.js';
4
+ import { loadNodeCrypto } from '@oxyhq/protocol';
5
5
  import { logger } from '../utils/loggerUtils.js';
6
6
  import { normalizeUserIdentity, normalizeUserIdentityOrNull } from '../utils/userIdentity.js';
7
7
  /**
@@ -1,4 +1,4 @@
1
- import { canonicalize } from '../crypto/canonicalJson.js';
1
+ import { canonicalize, verifySignature } from '@oxyhq/protocol';
2
2
  import { SignatureService } from '../crypto/signatureService.js';
3
3
  import { buildUserDid } from './OxyServices.identity.js';
4
4
  import { CACHE_TIMES } from './mixinHelpers.js';
@@ -150,7 +150,7 @@ export function parseAttestPayload(raw) {
150
150
  * key, matching the server which omits absent keys entirely) and checks the
151
151
  * `ES256K-DER-SHA256` signature against `attestation.publicKey`.
152
152
  *
153
- * NEVER throws: `SignatureService.verify` already swallows malformed-input
153
+ * NEVER throws: `verifySignature` already swallows malformed-input
154
154
  * errors and returns `false`, and an absent attestation short-circuits to
155
155
  * `false`. A pure, reusable helper (Commons can call it on a cached card).
156
156
  *
@@ -165,7 +165,7 @@ export async function verifyPublicCardAttestation(card, attestation) {
165
165
  if (!signature || !publicKey) {
166
166
  return false;
167
167
  }
168
- return SignatureService.verify(canonicalize(card), signature, publicKey);
168
+ return verifySignature(canonicalize(card), signature, publicKey);
169
169
  }
170
170
  export function OxyServicesCivicMixin(Base) {
171
171
  return class extends Base {
@@ -2,7 +2,7 @@
2
2
  * Language Methods Mixin
3
3
  */
4
4
  import { normalizeLanguageCode, getLanguageMetadata, getLanguageName, getNativeLanguageName } from '../utils/languageUtils.js';
5
- import { loadAsyncStorage } from '../utils/platformCrypto.js';
5
+ import { loadAsyncStorage } from '@oxyhq/protocol';
6
6
  import { isDev } from '../shared/utils/debugUtils.js';
7
7
  export function OxyServicesLanguageMixin(Base) {
8
8
  return class extends Base {