@oxyhq/services 6.10.6 → 6.10.8

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.
@@ -21,5 +21,5 @@ export declare const useInfiniteSecurityActivity: (options?: {
21
21
  limit?: number;
22
22
  eventType?: SecurityEventType;
23
23
  enabled?: boolean;
24
- }) => import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<SecurityActivityResponse, unknown>, Error>;
24
+ }) => import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/query-core").InfiniteData<SecurityActivityResponse, unknown>, Error>;
25
25
  //# sourceMappingURL=useSecurityQueries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSecurityQueries.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/hooks/queries/useSecurityQueries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjG;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,6FA2BF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAU,uFAgBnD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAU;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,mJA4BF,CAAC"}
1
+ {"version":3,"file":"useSecurityQueries.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/hooks/queries/useSecurityQueries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjG;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,6FA2BF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAU,uFAgBnD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAU;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,kJA4BF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSessionManagement.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useSessionManagement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,uBAAuB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,WAAW,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC/C,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAKD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,+KAalC,2BAA2B,KAAG,0BA2VhC,CAAC"}
1
+ {"version":3,"file":"useSessionManagement.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useSessionManagement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,uBAAuB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,WAAW,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC/C,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAKD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,+KAalC,2BAA2B,KAAG,0BAmWhC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"OxyContext.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/OxyContext.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"OxyContext.d.ts","sourceRoot":"","sources":["../../../../../src/ui/context/OxyContext.tsx"],"names":[],"mappings":"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"}
@@ -21,5 +21,5 @@ export declare const useInfiniteSecurityActivity: (options?: {
21
21
  limit?: number;
22
22
  eventType?: SecurityEventType;
23
23
  enabled?: boolean;
24
- }) => import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/react-query").InfiniteData<SecurityActivityResponse, unknown>, Error>;
24
+ }) => import("@tanstack/react-query").UseInfiniteQueryResult<import("@tanstack/query-core").InfiniteData<SecurityActivityResponse, unknown>, Error>;
25
25
  //# sourceMappingURL=useSecurityQueries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSecurityQueries.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/hooks/queries/useSecurityQueries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjG;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,6FA2BF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAU,uFAgBnD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAU;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,mJA4BF,CAAC"}
1
+ {"version":3,"file":"useSecurityQueries.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/hooks/queries/useSecurityQueries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjG;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,6FA2BF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAU,uFAgBnD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAU;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,kJA4BF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSessionManagement.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useSessionManagement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,uBAAuB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,WAAW,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC/C,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAKD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,+KAalC,2BAA2B,KAAG,0BA2VhC,CAAC"}
1
+ {"version":3,"file":"useSessionManagement.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useSessionManagement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,uBAAuB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,WAAW,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC/C,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAKD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,+KAalC,2BAA2B,KAAG,0BAmWhC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/services",
3
- "version": "6.10.6",
3
+ "version": "6.10.8",
4
4
  "description": "OxyHQ Expo/React Native SDK — UI components, screens, and native features",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -9,7 +9,7 @@ import {
9
9
  useState,
10
10
  type ReactNode,
11
11
  } from 'react';
12
- import { OxyServices } from '@oxyhq/core';
12
+ import { OxyServices, oxyClient } from '@oxyhq/core';
13
13
  import type { User, ApiError, SessionLoginResponse } from '@oxyhq/core';
14
14
  import type { ManagedAccount, CreateManagedAccountInput } from '@oxyhq/core';
15
15
  import { KeyManager } from '@oxyhq/core';
@@ -97,6 +97,77 @@ export interface OxyContextState {
97
97
 
98
98
  const OxyContext = createContext<OxyContextState | null>(null);
99
99
 
100
+ /**
101
+ * Minimal, decode-only shape of the session access-token JWT claims the
102
+ * `POST /auth/refresh` endpoint returns. We only read `sessionId` (and `userId`
103
+ * as a fallback). The token is already signed and verified server-side; the
104
+ * client decodes the payload purely to recover the session id — it does NOT and
105
+ * MUST NOT verify the signature.
106
+ */
107
+ interface RefreshAccessTokenClaims {
108
+ sessionId?: string;
109
+ userId?: string;
110
+ id?: string;
111
+ }
112
+
113
+ /**
114
+ * Decode the payload of a JWT WITHOUT verifying its signature.
115
+ *
116
+ * The server (`POST /auth/refresh`) has already minted and signed this access
117
+ * token; we only need to recover the `sessionId` claim from it on cold boot.
118
+ * Returns `null` for any malformed input rather than throwing, so a bad token
119
+ * simply falls through to the unauthenticated path.
120
+ *
121
+ * Implemented with manual base64url decoding (no `jwt-decode` dependency added
122
+ * to `@oxyhq/services`). Works on web (where this cold-boot path runs) via
123
+ * `atob`; if `atob` is unavailable (non-browser runtime) it is treated as
124
+ * undecodable and returns `null`.
125
+ */
126
+ function decodeAccessTokenClaims(token: string): RefreshAccessTokenClaims | null {
127
+ if (!token || typeof token !== 'string') {
128
+ return null;
129
+ }
130
+ const segments = token.split('.');
131
+ if (segments.length !== 3) {
132
+ return null;
133
+ }
134
+ const payloadSegment = segments[1];
135
+ if (!payloadSegment) {
136
+ return null;
137
+ }
138
+ try {
139
+ const base64 = payloadSegment.replace(/-/g, '+').replace(/_/g, '/');
140
+ const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '=');
141
+ if (typeof atob !== 'function') {
142
+ return null;
143
+ }
144
+ const json = decodeURIComponent(
145
+ atob(padded)
146
+ .split('')
147
+ .map((char) => `%${`00${char.charCodeAt(0).toString(16)}`.slice(-2)}`)
148
+ .join(''),
149
+ );
150
+ const parsed: unknown = JSON.parse(json);
151
+ if (parsed === null || typeof parsed !== 'object') {
152
+ return null;
153
+ }
154
+ const claims = parsed as Record<string, unknown>;
155
+ return {
156
+ sessionId: typeof claims.sessionId === 'string' ? claims.sessionId : undefined,
157
+ userId: typeof claims.userId === 'string' ? claims.userId : undefined,
158
+ id: typeof claims.id === 'string' ? claims.id : undefined,
159
+ };
160
+ } catch {
161
+ return null;
162
+ }
163
+ }
164
+
165
+ /** Server response shape of `POST /auth/refresh`. */
166
+ interface RefreshCookieResponse {
167
+ accessToken?: string;
168
+ sessionId?: string;
169
+ }
170
+
100
171
  export interface OxyContextProviderProps {
101
172
  children: ReactNode;
102
173
  oxyServices?: OxyServices;
@@ -190,6 +261,43 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
190
261
  const [initialized, setInitialized] = useState(false);
191
262
  const setAuthState = useAuthStore.setState;
192
263
 
264
+ // Keep the shared `oxyClient` singleton's token store in lockstep with the
265
+ // session owned by THIS provider's instance. Many apps construct their api
266
+ // clients against the exported `oxyClient` singleton (reading
267
+ // `oxyClient.getAccessToken()` to build Authorization headers) while passing
268
+ // only `baseURL` to OxyProvider — in which case the provider owns a DIFFERENT
269
+ // `OxyServices` instance and the singleton would otherwise never receive the
270
+ // token, producing `Authorization: Bearer null`.
271
+ //
272
+ // Subscribing to `onTokensChanged` mirrors EVERY token mutation — sign-in,
273
+ // session restore, switch, silent refresh, and sign-out/clear — onto the
274
+ // singleton at the single source of truth in @oxyhq/core, with no per-app
275
+ // plumbing and regardless of which auth code path fired.
276
+ //
277
+ // When the app passed the singleton itself as `oxyServices` (Mention's
278
+ // pattern), `oxyServices === oxyClient`, so we skip the redundant self-write
279
+ // and the subscription is a no-op mirror — fully backward compatible.
280
+ useEffect(() => {
281
+ if (oxyServices === oxyClient) {
282
+ return;
283
+ }
284
+
285
+ const applyToSingleton = (accessToken: string | null) => {
286
+ if (accessToken) {
287
+ oxyClient.setTokens(accessToken);
288
+ } else {
289
+ oxyClient.clearTokens();
290
+ }
291
+ };
292
+
293
+ // Seed the singleton with whatever token the instance already holds (it may
294
+ // have been planted synchronously before this effect ran — e.g. a token set
295
+ // during the same tick as mount), then keep it in sync going forward.
296
+ applyToSingleton(oxyServices.getAccessToken());
297
+
298
+ return oxyServices.onTokensChanged(applyToSingleton);
299
+ }, [oxyServices]);
300
+
193
301
  const logger = useCallback((message: string, err?: unknown) => {
194
302
  if (__DEV__) {
195
303
  console.warn(`[OxyContext] ${message}`, err);
@@ -198,16 +306,58 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
198
306
 
199
307
  const storageKeys = useMemo(() => getStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
200
308
 
201
- // Simple storage initialization - no complex hook needed
309
+ // Storage initialization.
310
+ //
311
+ // `storage` (state) drives render-time gating (`isStorageReady`) and the
312
+ // hooks below. But it is `null` for a brief window after mount while
313
+ // `createPlatformStorage()` resolves (a microtask on web; a dynamic
314
+ // `import()` on native). Any persistence path that fires during that window
315
+ // — e.g. an interactive FedCM sign-in the instant the screen mounts — would
316
+ // read `storage === null` and SILENTLY skip writing the session, leaving the
317
+ // user signed-in in-memory but with nothing to restore on reload.
318
+ //
319
+ // To make persistence robust regardless of timing we ALSO expose the storage
320
+ // as an awaitable promise (`getReadyStorage`). Persistence code awaits the
321
+ // ready instance instead of branching on the possibly-null state, so a write
322
+ // is never silently dropped just because it raced storage init.
202
323
  const storageRef = useRef<StorageInterface | null>(null);
203
324
  const [storage, setStorage] = useState<StorageInterface | null>(null);
204
325
 
326
+ // A single, stable deferred that resolves with the initialized storage. Built
327
+ // lazily via a ref initializer so the resolver is captured exactly once and
328
+ // the promise identity is stable across renders.
329
+ const buildStorageDeferred = () => {
330
+ let resolve: (storage: StorageInterface) => void = () => undefined;
331
+ const promise = new Promise<StorageInterface>((res) => {
332
+ resolve = res;
333
+ });
334
+ return { promise, resolve };
335
+ };
336
+ const storageReadyRef = useRef<ReturnType<typeof buildStorageDeferred> | null>(null);
337
+ if (storageReadyRef.current === null) {
338
+ storageReadyRef.current = buildStorageDeferred();
339
+ }
340
+ const storageReady = storageReadyRef.current;
341
+
342
+ // Resolve the storage instance that is guaranteed to be ready. Returns the
343
+ // already-initialized instance synchronously when available, otherwise awaits
344
+ // the init promise. Never resolves to `null`.
345
+ const getReadyStorage = useCallback((): Promise<StorageInterface> => {
346
+ if (storageRef.current) {
347
+ return Promise.resolve(storageRef.current);
348
+ }
349
+ return storageReady.promise;
350
+ }, [storageReady]);
351
+
205
352
  useEffect(() => {
206
353
  let mounted = true;
207
354
  createPlatformStorage()
208
355
  .then((storageInstance) => {
356
+ // Resolve the ready-promise even if the component unmounted: in-flight
357
+ // persistence awaiting it must still complete against a real store.
358
+ storageRef.current = storageInstance;
359
+ storageReady.resolve(storageInstance);
209
360
  if (mounted) {
210
- storageRef.current = storageInstance;
211
361
  setStorage(storageInstance);
212
362
  }
213
363
  })
@@ -225,7 +375,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
225
375
  return () => {
226
376
  mounted = false;
227
377
  };
228
- }, [logger, onError]);
378
+ }, [logger, onError, storageReady]);
229
379
 
230
380
 
231
381
  // Offline queuing is now handled by TanStack Query mutations
@@ -338,6 +488,148 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
338
488
  const clearSessionStateRef = useRef(clearSessionState);
339
489
  clearSessionStateRef.current = clearSessionState;
340
490
 
491
+ // Durable, navigation-safe session persistence.
492
+ //
493
+ // Writes the active-session id and appends the session id to the durable
494
+ // `session_ids` list, awaiting the READY storage instance (never the possibly
495
+ // -null `storage` state) so a write is never dropped because it raced storage
496
+ // init. Callers MUST invoke this BEFORE any work that can trigger a route
497
+ // navigation (`onAuthStateChange`) — navigation can interrupt a still-pending
498
+ // async write, which is exactly what once left `session_ids` empty after a
499
+ // successful sign-in. Shared by the FedCM/popup path and the cold-boot
500
+ // refresh-cookie restore so both land the same durable record.
501
+ const persistSessionDurably = useCallback(async (sessionId: string): Promise<void> => {
502
+ const readyStorage = await getReadyStorage();
503
+ await readyStorage.setItem(storageKeys.activeSessionId, sessionId);
504
+ const existingIds = await readyStorage.getItem(storageKeys.sessionIds);
505
+ let sessionIds: string[] = [];
506
+ try { sessionIds = existingIds ? JSON.parse(existingIds) : []; } catch { /* corrupted storage */ }
507
+ if (!sessionIds.includes(sessionId)) {
508
+ sessionIds.push(sessionId);
509
+ await readyStorage.setItem(storageKeys.sessionIds, JSON.stringify(sessionIds));
510
+ }
511
+ }, [getReadyStorage, storageKeys.activeSessionId, storageKeys.sessionIds]);
512
+
513
+ // Refs so the cold-boot restore can plant session state without widening its
514
+ // dependency array (mirrors the existing ref pattern above).
515
+ const setActiveSessionIdRef = useRef(setActiveSessionId);
516
+ setActiveSessionIdRef.current = setActiveSessionId;
517
+ const loginSuccessRef = useRef(loginSuccess);
518
+ loginSuccessRef.current = loginSuccess;
519
+ const onAuthStateChangeRef = useRef(onAuthStateChange);
520
+ onAuthStateChangeRef.current = onAuthStateChange;
521
+
522
+ // Cold-boot session restore via the secure refresh cookie (web only).
523
+ //
524
+ // On a hard reload the in-app, bearer-protected token fetch
525
+ // (`getTokenBySession` → `/session/token/:id`) 401s because there is no token
526
+ // in memory yet, which previously cleared the session and bounced the user to
527
+ // sign-in. Instead we call `POST {apiBaseUrl}/auth/refresh` with
528
+ // `credentials: 'include'` and NO Authorization header: the browser
529
+ // automatically attaches the first-party httpOnly `oxy_rt` cookie (set at
530
+ // login/signup/fedcm-exchange), the server validates + rotates it and returns
531
+ // a fresh session access token. JS never sees the refresh cookie (httpOnly) —
532
+ // that is the security property.
533
+ //
534
+ // Returns `true` when the session was restored (caller short-circuits the
535
+ // bearer path); `false` on 401 / no durable cookie / any failure (caller
536
+ // proceeds unauthenticated through the existing flow — nothing is cleared).
537
+ const restoreViaRefreshCookie = useCallback(async (): Promise<boolean> => {
538
+ if (!isWebBrowser()) {
539
+ return false;
540
+ }
541
+
542
+ const apiBaseUrl = oxyServices.getBaseURL();
543
+ if (!apiBaseUrl) {
544
+ return false;
545
+ }
546
+
547
+ let response: Response;
548
+ try {
549
+ // Direct credentialed, no-auth POST. We deliberately bypass the SDK's
550
+ // HttpService here: it would attach the (absent) bearer and does not send
551
+ // cookies. The refresh cookie is scoped to `Path=/auth/refresh` and sent
552
+ // automatically same-site.
553
+ response = await fetch(`${apiBaseUrl.replace(/\/$/, '')}/auth/refresh`, {
554
+ method: 'POST',
555
+ credentials: 'include',
556
+ headers: { Accept: 'application/json' },
557
+ });
558
+ } catch (fetchError) {
559
+ // Offline / network error — fall through to the cached/stored-session flow.
560
+ if (__DEV__) {
561
+ loggerUtil.debug('Refresh-cookie restore network error (expected when offline)', { component: 'OxyContext', method: 'restoreViaRefreshCookie' }, fetchError as unknown);
562
+ }
563
+ return false;
564
+ }
565
+
566
+ // 401 (no/expired/reused cookie) and any non-2xx → no durable session.
567
+ if (!response.ok) {
568
+ return false;
569
+ }
570
+
571
+ let payload: RefreshCookieResponse;
572
+ try {
573
+ payload = (await response.json()) as RefreshCookieResponse;
574
+ } catch {
575
+ return false;
576
+ }
577
+
578
+ const accessToken = payload.accessToken;
579
+ if (!accessToken) {
580
+ return false;
581
+ }
582
+
583
+ // Recover the session id from the (server-signed) access-token claims, or
584
+ // from the response body if the server included it. Decode-only; the server
585
+ // already verified the signature.
586
+ const claims = decodeAccessTokenClaims(accessToken);
587
+ const sessionId = payload.sessionId ?? claims?.sessionId;
588
+ if (!sessionId) {
589
+ // A token with no resolvable session id cannot drive multi-session state.
590
+ return false;
591
+ }
592
+
593
+ // Plant the fresh access token. The refresh token stays in the httpOnly
594
+ // cookie and is never touched by JS.
595
+ oxyServices.httpService.setTokens(accessToken);
596
+
597
+ // Fetch the full user with the freshly planted token.
598
+ let fullUser: User;
599
+ try {
600
+ fullUser = await oxyServices.getCurrentUser();
601
+ } catch (userError) {
602
+ // Token planted but profile fetch failed (e.g. transient network). Do not
603
+ // claim a restored session; fall through so the stored-session flow can
604
+ // retry. Leave the planted token in place — it is valid and harmless.
605
+ if (__DEV__) {
606
+ loggerUtil.debug('Refresh-cookie restore: getCurrentUser failed', { component: 'OxyContext', method: 'restoreViaRefreshCookie' }, userError as unknown);
607
+ }
608
+ return false;
609
+ }
610
+
611
+ const userId = fullUser.id?.toString() ?? claims?.userId ?? '';
612
+ const now = new Date();
613
+ const clientSession: ClientSession = {
614
+ sessionId,
615
+ deviceId: '',
616
+ expiresAt: new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
617
+ lastActive: now.toISOString(),
618
+ userId,
619
+ isCurrent: true,
620
+ };
621
+
622
+ // Restore the active session into the multi-session store (merge: keep any
623
+ // other sessions intact) and durably persist BEFORE notifying listeners.
624
+ updateSessionsRef.current([clientSession], { merge: true });
625
+ setActiveSessionIdRef.current(sessionId);
626
+ await persistSessionDurably(sessionId);
627
+
628
+ loginSuccessRef.current(fullUser);
629
+ onAuthStateChangeRef.current?.(fullUser);
630
+ return true;
631
+ }, [oxyServices, persistSessionDurably]);
632
+
341
633
  const restoreSessionsFromStorage = useCallback(async (): Promise<void> => {
342
634
  if (!storage) {
343
635
  return;
@@ -346,6 +638,15 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
346
638
  setTokenReady(false);
347
639
 
348
640
  try {
641
+ // Web cold-boot fast path: restore the active session from the secure
642
+ // httpOnly refresh cookie before the bearer-protected stored-session
643
+ // validation (which 401s on a hard reload). On success we are signed in
644
+ // from the cookie alone — no FedCM needed. On failure we fall through to
645
+ // the existing stored-session flow below; nothing is cleared.
646
+ if (await restoreViaRefreshCookie()) {
647
+ return;
648
+ }
649
+
349
650
  const storedSessionIdsJson = await storage.getItem(storageKeys.sessionIds);
350
651
  const storedSessionIds: string[] = storedSessionIdsJson ? JSON.parse(storedSessionIdsJson) : [];
351
652
  const storedActiveSessionId = await storage.getItem(storageKeys.activeSessionId);
@@ -436,6 +737,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
436
737
  storage,
437
738
  storageKeys.activeSessionId,
438
739
  storageKeys.sessionIds,
740
+ restoreViaRefreshCookie,
439
741
  ]);
440
742
 
441
743
  useEffect(() => {
@@ -480,8 +782,25 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
480
782
  updateSessions([clientSession], { merge: true });
481
783
  setActiveSessionId(session.sessionId);
482
784
 
483
- // Fetch the full user profile now that we have a valid access token.
484
- // The session only carries MinimalUserData; the store and callbacks expect a full User.
785
+ // Persist to storage BEFORE fetching the profile and BEFORE notifying the
786
+ // auth-state-change callback. The token is planted and the in-memory store
787
+ // is updated above; durably committing the session id here — ahead of
788
+ // `getCurrentUser()` / `loginSuccess` / `onAuthStateChange` — is critical
789
+ // because `onAuthStateChange` triggers a route navigation that can
790
+ // interrupt/supersede a still-pending async write. Persisting first
791
+ // guarantees the durable record lands; that is exactly what was missing
792
+ // when `oxy_session_session_ids` came back empty after a successful FedCM
793
+ // sign-in (the user appeared logged in until reload, then had no session to
794
+ // restore). `persistSessionDurably` awaits the READY storage instance rather
795
+ // than reading the possibly-null `storage` state, so a sign-in fired the
796
+ // instant the screen mounts (before storage-init populates state) is not
797
+ // silently dropped.
798
+ await persistSessionDurably(session.sessionId);
799
+
800
+ // Fetch the full user profile now that we have a valid access token and the
801
+ // session is durably persisted. The session only carries MinimalUserData;
802
+ // the store and callbacks expect a full User. The navigation kicked off by
803
+ // `onAuthStateChange` now happens only after the durable write is committed.
485
804
  let fullUser: User;
486
805
  try {
487
806
  fullUser = await oxyServices.getCurrentUser();
@@ -492,19 +811,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
492
811
  }
493
812
  loginSuccess(fullUser);
494
813
  onAuthStateChange?.(fullUser);
495
-
496
- // Persist to storage
497
- if (storage) {
498
- await storage.setItem(storageKeys.activeSessionId, session.sessionId);
499
- const existingIds = await storage.getItem(storageKeys.sessionIds);
500
- let sessionIds: string[] = [];
501
- try { sessionIds = existingIds ? JSON.parse(existingIds) : []; } catch { /* corrupted storage */ }
502
- if (!sessionIds.includes(session.sessionId)) {
503
- sessionIds.push(session.sessionId);
504
- await storage.setItem(storageKeys.sessionIds, JSON.stringify(sessionIds));
505
- }
506
- }
507
- }, [oxyServices, updateSessions, setActiveSessionId, loginSuccess, onAuthStateChange, storage, storageKeys]);
814
+ }, [oxyServices, updateSessions, setActiveSessionId, loginSuccess, onAuthStateChange, persistSessionDurably]);
508
815
 
509
816
  // Enable web SSO only after local storage check completes and no user found
510
817
  const shouldTryWebSSO = isWebBrowser() && tokenReady && !user && initialized;
@@ -166,7 +166,15 @@ export const useSessionManagement = ({
166
166
  setSessions([]);
167
167
  setActiveSessionId(null);
168
168
  logoutStore();
169
-
169
+
170
+ // Clear the access token on the client instance. Without this the
171
+ // TokenStore retained the stale bearer until the next 401, leaving the
172
+ // instance "logged in" at the HTTP layer and — via OxyProvider's
173
+ // token-change mirror — leaking that stale token onto the shared
174
+ // `oxyClient` singleton after sign-out. Clearing here fires
175
+ // `onTokensChanged(null)`, propagating the logged-out state everywhere.
176
+ oxyServices.clearTokens();
177
+
170
178
  // Clear TanStack Query cache (in-memory)
171
179
  if (queryClient) {
172
180
  queryClient.clear();
@@ -185,7 +193,7 @@ export const useSessionManagement = ({
185
193
 
186
194
  await clearSessionStorage();
187
195
  onAuthStateChange?.(null);
188
- }, [clearSessionStorage, logoutStore, onAuthStateChange, queryClient, storage, logger]);
196
+ }, [clearSessionStorage, logoutStore, onAuthStateChange, oxyServices, queryClient, storage, logger]);
189
197
 
190
198
  const activateSession = useCallback(
191
199
  async (sessionId: string, user: User): Promise<void> => {