@oxyhq/services 5.7.4 → 5.8.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 (252) hide show
  1. package/README.md +125 -268
  2. package/lib/commonjs/core/index.js +172 -0
  3. package/lib/commonjs/core/index.js.map +1 -1
  4. package/lib/commonjs/index.js +88 -29
  5. package/lib/commonjs/index.js.map +1 -1
  6. package/lib/commonjs/node/createAuth.js +585 -7
  7. package/lib/commonjs/node/createAuth.js.map +1 -1
  8. package/lib/commonjs/node/index.js +31 -41
  9. package/lib/commonjs/node/index.js.map +1 -1
  10. package/lib/commonjs/ui/components/Avatar.js +15 -6
  11. package/lib/commonjs/ui/components/Avatar.js.map +1 -1
  12. package/lib/commonjs/ui/components/GroupedItem.js +58 -13
  13. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
  14. package/lib/commonjs/ui/components/GroupedSection.js +7 -1
  15. package/lib/commonjs/ui/components/GroupedSection.js.map +1 -1
  16. package/lib/commonjs/ui/components/Header.js +322 -0
  17. package/lib/commonjs/ui/components/Header.js.map +1 -0
  18. package/lib/commonjs/ui/components/OxyProvider.js +23 -7
  19. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  20. package/lib/commonjs/ui/components/index.js +7 -0
  21. package/lib/commonjs/ui/components/index.js.map +1 -1
  22. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +1 -1
  23. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
  24. package/lib/commonjs/ui/components/internal/TextField.js +606 -546
  25. package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
  26. package/lib/commonjs/ui/components/internal/TextField.md +436 -0
  27. package/lib/commonjs/ui/context/OxyContext.js +122 -78
  28. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  29. package/lib/commonjs/ui/hooks/useSessionSocket.js +5 -2
  30. package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -1
  31. package/lib/commonjs/ui/index.js +1 -16
  32. package/lib/commonjs/ui/index.js.map +1 -1
  33. package/lib/commonjs/ui/navigation/OxyRouter.js +1 -1
  34. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  35. package/lib/commonjs/ui/screens/AccountCenterScreen.js +6 -6
  36. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/AccountManagementDemo.js +3 -3
  38. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -1
  39. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +241 -598
  40. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +1151 -406
  42. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +135 -237
  44. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  45. package/lib/commonjs/ui/screens/AppInfoScreen.js +246 -463
  46. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  47. package/lib/commonjs/ui/screens/FeedbackScreen.js +3 -3
  48. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +808 -650
  50. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  51. package/lib/commonjs/ui/screens/RecoverAccountScreen.js +51 -72
  52. package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/SessionManagementScreen.js +11 -29
  54. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/SignInScreen.js +30 -303
  56. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  57. package/lib/commonjs/ui/screens/SignUpScreen.js +4 -4
  58. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  59. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +19 -31
  60. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  61. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +7 -10
  62. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  63. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +11 -5
  64. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
  65. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +11 -4
  66. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
  67. package/lib/commonjs/ui/stores/authStore.js +12 -0
  68. package/lib/commonjs/ui/stores/authStore.js.map +1 -1
  69. package/lib/commonjs/ui/styles/authStyles.js +337 -0
  70. package/lib/commonjs/ui/styles/authStyles.js.map +1 -0
  71. package/lib/commonjs/ui/styles/index.js +11 -0
  72. package/lib/commonjs/ui/styles/index.js.map +1 -1
  73. package/lib/module/core/index.js +172 -0
  74. package/lib/module/core/index.js.map +1 -1
  75. package/lib/module/index.js +26 -4
  76. package/lib/module/index.js.map +1 -1
  77. package/lib/module/node/createAuth.js +584 -7
  78. package/lib/module/node/createAuth.js.map +1 -1
  79. package/lib/module/node/index.js +8 -12
  80. package/lib/module/node/index.js.map +1 -1
  81. package/lib/module/ui/components/Avatar.js +15 -6
  82. package/lib/module/ui/components/Avatar.js.map +1 -1
  83. package/lib/module/ui/components/GroupedItem.js +59 -14
  84. package/lib/module/ui/components/GroupedItem.js.map +1 -1
  85. package/lib/module/ui/components/GroupedSection.js +7 -1
  86. package/lib/module/ui/components/GroupedSection.js.map +1 -1
  87. package/lib/module/ui/components/Header.js +317 -0
  88. package/lib/module/ui/components/Header.js.map +1 -0
  89. package/lib/module/ui/components/OxyProvider.js +25 -9
  90. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  91. package/lib/module/ui/components/index.js +1 -0
  92. package/lib/module/ui/components/index.js.map +1 -1
  93. package/lib/module/ui/components/internal/GroupedPillButtons.js +1 -1
  94. package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
  95. package/lib/module/ui/components/internal/TextField.js +607 -547
  96. package/lib/module/ui/components/internal/TextField.js.map +1 -1
  97. package/lib/module/ui/components/internal/TextField.md +436 -0
  98. package/lib/module/ui/context/OxyContext.js +121 -77
  99. package/lib/module/ui/context/OxyContext.js.map +1 -1
  100. package/lib/module/ui/hooks/useSessionSocket.js +5 -2
  101. package/lib/module/ui/hooks/useSessionSocket.js.map +1 -1
  102. package/lib/module/ui/index.js +1 -16
  103. package/lib/module/ui/index.js.map +1 -1
  104. package/lib/module/ui/navigation/OxyRouter.js +1 -1
  105. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  106. package/lib/module/ui/screens/AccountCenterScreen.js +6 -6
  107. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  108. package/lib/module/ui/screens/AccountManagementDemo.js +3 -3
  109. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -1
  110. package/lib/module/ui/screens/AccountOverviewScreen.js +242 -597
  111. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  112. package/lib/module/ui/screens/AccountSettingsScreen.js +1152 -407
  113. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  114. package/lib/module/ui/screens/AccountSwitcherScreen.js +135 -237
  115. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  116. package/lib/module/ui/screens/AppInfoScreen.js +248 -465
  117. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  118. package/lib/module/ui/screens/FeedbackScreen.js +3 -3
  119. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  120. package/lib/module/ui/screens/PaymentGatewayScreen.js +809 -651
  121. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  122. package/lib/module/ui/screens/RecoverAccountScreen.js +53 -74
  123. package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
  124. package/lib/module/ui/screens/SessionManagementScreen.js +11 -29
  125. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  126. package/lib/module/ui/screens/SignInScreen.js +32 -305
  127. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  128. package/lib/module/ui/screens/SignUpScreen.js +5 -5
  129. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  130. package/lib/module/ui/screens/internal/SignInPasswordStep.js +19 -31
  131. package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  132. package/lib/module/ui/screens/internal/SignInUsernameStep.js +7 -10
  133. package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  134. package/lib/module/ui/screens/internal/SignUpIdentityStep.js +11 -5
  135. package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
  136. package/lib/module/ui/screens/internal/SignUpSecurityStep.js +11 -4
  137. package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
  138. package/lib/module/ui/stores/authStore.js +12 -0
  139. package/lib/module/ui/stores/authStore.js.map +1 -1
  140. package/lib/module/ui/styles/authStyles.js +332 -0
  141. package/lib/module/ui/styles/authStyles.js.map +1 -0
  142. package/lib/module/ui/styles/index.js +1 -0
  143. package/lib/module/ui/styles/index.js.map +1 -1
  144. package/lib/typescript/core/index.d.ts +67 -0
  145. package/lib/typescript/core/index.d.ts.map +1 -1
  146. package/lib/typescript/index.d.ts +13 -3
  147. package/lib/typescript/index.d.ts.map +1 -1
  148. package/lib/typescript/node/createAuth.d.ts +112 -0
  149. package/lib/typescript/node/createAuth.d.ts.map +1 -1
  150. package/lib/typescript/node/index.d.ts +3 -7
  151. package/lib/typescript/node/index.d.ts.map +1 -1
  152. package/lib/typescript/ui/components/Avatar.d.ts.map +1 -1
  153. package/lib/typescript/ui/components/GroupedItem.d.ts +6 -0
  154. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
  155. package/lib/typescript/ui/components/GroupedSection.d.ts +6 -0
  156. package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -1
  157. package/lib/typescript/ui/components/Header.d.ts +22 -0
  158. package/lib/typescript/ui/components/Header.d.ts.map +1 -0
  159. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  160. package/lib/typescript/ui/components/index.d.ts +1 -0
  161. package/lib/typescript/ui/components/index.d.ts.map +1 -1
  162. package/lib/typescript/ui/components/internal/TextField.d.ts +31 -16
  163. package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
  164. package/lib/typescript/ui/context/OxyContext.d.ts +5 -2
  165. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  166. package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -1
  167. package/lib/typescript/ui/index.d.ts +1 -2
  168. package/lib/typescript/ui/index.d.ts.map +1 -1
  169. package/lib/typescript/ui/navigation/types.d.ts +9 -2
  170. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  171. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  172. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  173. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  174. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
  175. package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  176. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +5 -1
  177. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
  178. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  179. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  180. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +1 -1
  181. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
  182. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +0 -1
  183. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
  184. package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +1 -1
  185. package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +1 -1
  186. package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
  187. package/lib/typescript/ui/styles/authStyles.d.ts +326 -0
  188. package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -0
  189. package/lib/typescript/ui/styles/index.d.ts +1 -0
  190. package/lib/typescript/ui/styles/index.d.ts.map +1 -1
  191. package/package.json +1 -6
  192. package/src/core/index.ts +189 -0
  193. package/src/index.ts +72 -4
  194. package/src/node/createAuth.ts +623 -7
  195. package/src/node/index.ts +20 -18
  196. package/src/ui/components/Avatar.tsx +11 -5
  197. package/src/ui/components/GroupedItem.tsx +57 -9
  198. package/src/ui/components/GroupedSection.tsx +12 -0
  199. package/src/ui/components/Header.tsx +364 -0
  200. package/src/ui/components/OxyProvider.tsx +31 -15
  201. package/src/ui/components/index.ts +1 -0
  202. package/src/ui/components/internal/GroupedPillButtons.tsx +1 -1
  203. package/src/ui/components/internal/TextField.md +436 -0
  204. package/src/ui/components/internal/TextField.tsx +720 -620
  205. package/src/ui/context/OxyContext.tsx +150 -63
  206. package/src/ui/hooks/useSessionSocket.ts +5 -2
  207. package/src/ui/index.ts +1 -19
  208. package/src/ui/navigation/OxyRouter.tsx +1 -1
  209. package/src/ui/navigation/types.ts +10 -2
  210. package/src/ui/screens/AccountCenterScreen.tsx +5 -5
  211. package/src/ui/screens/AccountManagementDemo.tsx +9 -9
  212. package/src/ui/screens/AccountOverviewScreen.tsx +265 -414
  213. package/src/ui/screens/AccountSettingsScreen.tsx +1165 -403
  214. package/src/ui/screens/AccountSwitcherScreen.tsx +158 -202
  215. package/src/ui/screens/AppInfoScreen.tsx +270 -497
  216. package/src/ui/screens/FeedbackScreen.tsx +3 -3
  217. package/src/ui/screens/PaymentGatewayScreen.tsx +668 -365
  218. package/src/ui/screens/ProfileScreen.tsx +5 -5
  219. package/src/ui/screens/RecoverAccountScreen.tsx +46 -74
  220. package/src/ui/screens/SessionManagementScreen.tsx +14 -22
  221. package/src/ui/screens/SignInScreen.tsx +27 -294
  222. package/src/ui/screens/SignUpScreen.tsx +5 -5
  223. package/src/ui/screens/internal/SignInPasswordStep.tsx +11 -22
  224. package/src/ui/screens/internal/SignInUsernameStep.tsx +3 -10
  225. package/src/ui/screens/internal/SignUpIdentityStep.tsx +2 -5
  226. package/src/ui/screens/internal/SignUpSecurityStep.tsx +3 -4
  227. package/src/ui/stores/authStore.ts +12 -0
  228. package/src/ui/styles/authStyles.ts +352 -0
  229. package/src/ui/styles/index.ts +1 -0
  230. package/lib/commonjs/node/middleware.js +0 -227
  231. package/lib/commonjs/node/middleware.js.map +0 -1
  232. package/lib/commonjs/ui/zero-config/index.js +0 -25
  233. package/lib/commonjs/ui/zero-config/index.js.map +0 -1
  234. package/lib/commonjs/ui/zero-config/provider.js +0 -278
  235. package/lib/commonjs/ui/zero-config/provider.js.map +0 -1
  236. package/lib/module/node/middleware.js +0 -199
  237. package/lib/module/node/middleware.js.map +0 -1
  238. package/lib/module/ui/zero-config/index.js +0 -8
  239. package/lib/module/ui/zero-config/index.js.map +0 -1
  240. package/lib/module/ui/zero-config/provider.js +0 -270
  241. package/lib/module/ui/zero-config/provider.js.map +0 -1
  242. package/lib/typescript/node/middleware.d.ts +0 -92
  243. package/lib/typescript/node/middleware.d.ts.map +0 -1
  244. package/lib/typescript/ui/zero-config/index.d.ts +0 -5
  245. package/lib/typescript/ui/zero-config/index.d.ts.map +0 -1
  246. package/lib/typescript/ui/zero-config/provider.d.ts +0 -84
  247. package/lib/typescript/ui/zero-config/provider.d.ts.map +0 -1
  248. package/src/__tests__/middleware.test.ts +0 -105
  249. package/src/__tests__/setup.ts +0 -10
  250. package/src/node/middleware.ts +0 -234
  251. package/src/ui/zero-config/index.ts +0 -11
  252. package/src/ui/zero-config/provider.tsx +0 -310
@@ -1,234 +0,0 @@
1
- /**
2
- * Zero-config Express middleware for OxyHQ Services authentication
3
- *
4
- * This provides a simple, one-line solution for adding authentication to Express apps.
5
- * Simply import and use: app.use('/api', createOxyAuth())
6
- */
7
-
8
- import { OxyServices } from '../core';
9
- import { ApiError } from '../models/interfaces';
10
-
11
- export interface OxyAuthConfig {
12
- /** Base URL of your Oxy API server */
13
- baseURL?: string;
14
- /** Whether to load full user data (default: true) */
15
- loadUser?: boolean;
16
- /** Routes that don't require authentication */
17
- publicPaths?: string[];
18
- /** Custom error handler */
19
- onError?: (error: ApiError, req: any, res: any) => void;
20
- }
21
-
22
- export interface AuthenticatedRequest {
23
- user?: any;
24
- userId?: string;
25
- accessToken?: string;
26
- }
27
-
28
- /**
29
- * Creates zero-config authentication middleware for Express.js
30
- *
31
- * @example
32
- * ```typescript
33
- * import express from 'express';
34
- * import { createOxyAuth } from '@oxyhq/services/node';
35
- *
36
- * const app = express();
37
- *
38
- * // Zero-config auth for all /api routes
39
- * app.use('/api', createOxyAuth());
40
- *
41
- * // Now all routes under /api automatically have req.user available
42
- * app.get('/api/profile', (req, res) => {
43
- * res.json({ user: req.user }); // req.user is automatically available
44
- * });
45
- * ```
46
- */
47
- export function createOxyAuth(config: OxyAuthConfig = {}) {
48
- const {
49
- baseURL = process.env.OXY_API_URL || 'http://localhost:3001',
50
- loadUser = true,
51
- publicPaths = [],
52
- onError
53
- } = config;
54
-
55
- const oxy = new OxyServices({ baseURL });
56
-
57
- return async (req: any, res: any, next: any) => {
58
- // Check if this is a public path
59
- const isPublicPath = publicPaths.some(path =>
60
- req.path === path || req.path.startsWith(path + '/')
61
- );
62
-
63
- if (isPublicPath) {
64
- return next();
65
- }
66
-
67
- try {
68
- const authHeader = req.headers['authorization'];
69
- const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
70
-
71
- if (!token) {
72
- const error: ApiError = {
73
- message: 'Access token required',
74
- code: 'MISSING_TOKEN',
75
- status: 401
76
- };
77
-
78
- if (onError) {
79
- return onError(error, req, res);
80
- }
81
-
82
- return res.status(401).json({
83
- error: 'Access token required',
84
- code: 'MISSING_TOKEN'
85
- });
86
- }
87
-
88
- // Validate token using the OxyServices client
89
- const authResult = await oxy.authenticateToken(token);
90
-
91
- if (!authResult.valid) {
92
- const error: ApiError = {
93
- message: authResult.error || 'Invalid token',
94
- code: 'INVALID_TOKEN',
95
- status: 403
96
- };
97
-
98
- if (onError) {
99
- return onError(error, req, res);
100
- }
101
-
102
- return res.status(403).json({
103
- error: authResult.error || 'Invalid token',
104
- code: 'INVALID_TOKEN'
105
- });
106
- }
107
-
108
- // Attach user data to request
109
- req.userId = authResult.userId;
110
- req.accessToken = token;
111
-
112
- if (loadUser && authResult.user) {
113
- req.user = authResult.user;
114
- } else {
115
- req.user = { id: authResult.userId };
116
- }
117
-
118
- next();
119
- } catch (error: any) {
120
- const apiError: ApiError = {
121
- message: error.message || 'Authentication failed',
122
- code: error.code || 'AUTH_ERROR',
123
- status: error.status || 500
124
- };
125
-
126
- if (onError) {
127
- return onError(apiError, req, res);
128
- }
129
-
130
- res.status(apiError.status).json({
131
- error: apiError.message,
132
- code: apiError.code
133
- });
134
- }
135
- };
136
- }
137
-
138
- /**
139
- * Creates optional authentication middleware
140
- * This middleware will attach user data if a valid token is present, but won't fail if missing
141
- *
142
- * @example
143
- * ```typescript
144
- * import { createOptionalOxyAuth } from '@oxyhq/services/node';
145
- *
146
- * app.use('/api', createOptionalOxyAuth());
147
- *
148
- * app.get('/api/content', (req, res) => {
149
- * if (req.user) {
150
- * // User is authenticated, show personalized content
151
- * res.json({ content: 'personalized', user: req.user });
152
- * } else {
153
- * // Anonymous user, show public content
154
- * res.json({ content: 'public' });
155
- * }
156
- * });
157
- * ```
158
- */
159
- export function createOptionalOxyAuth(config: OxyAuthConfig = {}) {
160
- const {
161
- baseURL = process.env.OXY_API_URL || 'http://localhost:3001',
162
- loadUser = true
163
- } = config;
164
-
165
- const oxy = new OxyServices({ baseURL });
166
-
167
- return async (req: any, res: any, next: any) => {
168
- try {
169
- const authHeader = req.headers['authorization'];
170
- const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
171
-
172
- if (!token) {
173
- // No token provided, continue without authentication
174
- return next();
175
- }
176
-
177
- // Validate token using the OxyServices client
178
- const authResult = await oxy.authenticateToken(token);
179
-
180
- if (authResult.valid) {
181
- // Attach user data to request if token is valid
182
- req.userId = authResult.userId;
183
- req.accessToken = token;
184
-
185
- if (loadUser && authResult.user) {
186
- req.user = authResult.user;
187
- } else {
188
- req.user = { id: authResult.userId };
189
- }
190
- }
191
-
192
- next();
193
- } catch (error) {
194
- // If there's an error, continue without authentication
195
- // This makes the middleware truly optional
196
- next();
197
- }
198
- };
199
- }
200
-
201
- /**
202
- * Utility function to quickly set up a complete Express app with authentication
203
- *
204
- * @example
205
- * ```typescript
206
- * import { createOxyExpressApp } from '@oxyhq/services/node';
207
- *
208
- * const app = createOxyExpressApp();
209
- *
210
- * // All routes automatically have authentication and req.user available
211
- * app.get('/api/profile', (req, res) => {
212
- * res.json({ user: req.user });
213
- * });
214
- *
215
- * app.listen(3000);
216
- * ```
217
- */
218
- export function createOxyExpressApp(config: OxyAuthConfig & {
219
- /** Express app configuration */
220
- cors?: boolean;
221
- /** JSON body parser limit */
222
- jsonLimit?: string;
223
- /** Additional middleware to apply */
224
- middleware?: any[];
225
- } = {}) {
226
- // This is a lightweight helper - users should import express themselves
227
- // We'll provide the middleware setup instructions instead
228
-
229
- throw new Error('createOxyExpressApp is not implemented yet. Please use createOxyAuth() middleware with your existing Express app.');
230
- }
231
-
232
- // Re-export for convenience
233
- export { OxyServices } from '../core';
234
- export * from '../models/interfaces';
@@ -1,11 +0,0 @@
1
- /**
2
- * Zero-config exports for OxyHQ Services
3
- */
4
-
5
- export {
6
- OxyZeroConfigProvider,
7
- useOxyZeroConfig,
8
- useOxyApi,
9
- type OxyZeroConfigState,
10
- type OxyZeroConfigProviderProps
11
- } from './provider';
@@ -1,310 +0,0 @@
1
- /**
2
- * Zero-config OxyHQ Provider and Hook for React/React Native
3
- *
4
- * This provides a simplified, one-line setup for frontend authentication
5
- * with automatic token management and API integration.
6
- */
7
-
8
- import React, { createContext, useContext, useEffect, useState, ReactNode, useCallback } from 'react';
9
- import { OxyServices } from '../../core';
10
- import { User, LoginResponse } from '../../models/interfaces';
11
-
12
- export interface OxyZeroConfigState {
13
- // Authentication state
14
- user: User | null;
15
- isAuthenticated: boolean;
16
- isLoading: boolean;
17
- error: string | null;
18
-
19
- // Simple auth methods
20
- login: (username: string, password: string) => Promise<User>;
21
- logout: () => Promise<void>;
22
- register: (username: string, email: string, password: string) => Promise<User>;
23
-
24
- // Access to the OxyServices client
25
- api: OxyServices;
26
- }
27
-
28
- const OxyZeroConfigContext = createContext<OxyZeroConfigState | null>(null);
29
-
30
- export interface OxyZeroConfigProviderProps {
31
- children: ReactNode;
32
- /** Base URL of your Oxy API server (defaults to process.env.REACT_APP_OXY_API_URL or http://localhost:3001) */
33
- apiUrl?: string;
34
- /** Called when authentication state changes */
35
- onAuthChange?: (user: User | null) => void;
36
- /** Storage key prefix (default: 'oxy_zero') */
37
- storagePrefix?: string;
38
- }
39
-
40
- /**
41
- * Zero-config provider for OxyHQ Services
42
- *
43
- * @example
44
- * ```tsx
45
- * import { OxyZeroConfigProvider } from '@oxyhq/services/ui';
46
- *
47
- * function App() {
48
- * return (
49
- * <OxyZeroConfigProvider>
50
- * <MyApp />
51
- * </OxyZeroConfigProvider>
52
- * );
53
- * }
54
- * ```
55
- */
56
- export const OxyZeroConfigProvider: React.FC<OxyZeroConfigProviderProps> = ({
57
- children,
58
- apiUrl,
59
- onAuthChange,
60
- storagePrefix = 'oxy_zero'
61
- }) => {
62
- // Determine API URL with fallbacks
63
- const finalApiUrl = apiUrl ||
64
- (typeof process !== 'undefined' && process.env?.REACT_APP_OXY_API_URL) ||
65
- 'http://localhost:3001';
66
-
67
- // Initialize OxyServices
68
- const [api] = useState(() => new OxyServices({ baseURL: finalApiUrl }));
69
-
70
- // State
71
- const [user, setUser] = useState<User | null>(null);
72
- const [isLoading, setIsLoading] = useState(true);
73
- const [error, setError] = useState<string | null>(null);
74
-
75
- const isAuthenticated = user !== null;
76
-
77
- // Storage helpers
78
- const getStorageKey = (key: string) => `${storagePrefix}_${key}`;
79
-
80
- const saveToStorage = useCallback((key: string, value: string) => {
81
- try {
82
- if (typeof localStorage !== 'undefined') {
83
- localStorage.setItem(getStorageKey(key), value);
84
- }
85
- } catch (error) {
86
- console.warn('Failed to save to storage:', error);
87
- }
88
- }, [storagePrefix]);
89
-
90
- const getFromStorage = useCallback((key: string): string | null => {
91
- try {
92
- if (typeof localStorage !== 'undefined') {
93
- return localStorage.getItem(getStorageKey(key));
94
- }
95
- } catch (error) {
96
- console.warn('Failed to read from storage:', error);
97
- }
98
- return null;
99
- }, [storagePrefix]);
100
-
101
- const removeFromStorage = useCallback((key: string) => {
102
- try {
103
- if (typeof localStorage !== 'undefined') {
104
- localStorage.removeItem(getStorageKey(key));
105
- }
106
- } catch (error) {
107
- console.warn('Failed to remove from storage:', error);
108
- }
109
- }, [storagePrefix]);
110
-
111
- // Initialize authentication state
112
- useEffect(() => {
113
- const initAuth = async () => {
114
- try {
115
- setIsLoading(true);
116
- setError(null);
117
-
118
- // Try to restore tokens from storage
119
- const savedAccessToken = getFromStorage('accessToken');
120
- const savedRefreshToken = getFromStorage('refreshToken');
121
-
122
- if (savedAccessToken && savedRefreshToken) {
123
- // Set tokens in the API client
124
- api.setTokens(savedAccessToken, savedRefreshToken);
125
-
126
- // Validate the token
127
- const isValid = await api.validate();
128
- if (isValid) {
129
- // Load user data
130
- const currentUser = await api.getCurrentUser();
131
- setUser(currentUser);
132
-
133
- if (onAuthChange) {
134
- onAuthChange(currentUser);
135
- }
136
- } else {
137
- // Invalid token, clear storage
138
- removeFromStorage('accessToken');
139
- removeFromStorage('refreshToken');
140
- api.clearTokens();
141
- }
142
- }
143
- } catch (error: any) {
144
- console.warn('Failed to restore authentication:', error);
145
- setError('Failed to restore authentication');
146
-
147
- // Clear invalid tokens
148
- removeFromStorage('accessToken');
149
- removeFromStorage('refreshToken');
150
- api.clearTokens();
151
- } finally {
152
- setIsLoading(false);
153
- }
154
- };
155
-
156
- initAuth();
157
- }, [api, getFromStorage, removeFromStorage, onAuthChange]);
158
-
159
- // Login method
160
- const login = useCallback(async (username: string, password: string): Promise<User> => {
161
- try {
162
- setIsLoading(true);
163
- setError(null);
164
-
165
- const response: LoginResponse = await api.login(username, password);
166
-
167
- // Save tokens to storage
168
- if (response.accessToken) {
169
- saveToStorage('accessToken', response.accessToken);
170
- }
171
- if (response.refreshToken) {
172
- saveToStorage('refreshToken', response.refreshToken);
173
- }
174
-
175
- // Update state
176
- setUser(response.user);
177
-
178
- if (onAuthChange) {
179
- onAuthChange(response.user);
180
- }
181
-
182
- return response.user;
183
- } catch (error: any) {
184
- const errorMessage = error.message || 'Login failed';
185
- setError(errorMessage);
186
- throw new Error(errorMessage);
187
- } finally {
188
- setIsLoading(false);
189
- }
190
- }, [api, saveToStorage, onAuthChange]);
191
-
192
- // Logout method
193
- const logout = useCallback(async (): Promise<void> => {
194
- try {
195
- setIsLoading(true);
196
- await api.logout();
197
- } catch (error) {
198
- console.warn('Logout API call failed:', error);
199
- } finally {
200
- // Always clean up local state and storage
201
- removeFromStorage('accessToken');
202
- removeFromStorage('refreshToken');
203
- api.clearTokens();
204
- setUser(null);
205
- setError(null);
206
- setIsLoading(false);
207
-
208
- if (onAuthChange) {
209
- onAuthChange(null);
210
- }
211
- }
212
- }, [api, removeFromStorage, onAuthChange]);
213
-
214
- // Register method
215
- const register = useCallback(async (username: string, email: string, password: string): Promise<User> => {
216
- try {
217
- setIsLoading(true);
218
- setError(null);
219
-
220
- const response = await api.signUp(username, email, password);
221
-
222
- // Save token from registration
223
- if (response.token) {
224
- saveToStorage('accessToken', response.token);
225
- // Note: signUp doesn't return refreshToken in current API
226
- }
227
-
228
- // Update state
229
- setUser(response.user);
230
-
231
- if (onAuthChange) {
232
- onAuthChange(response.user);
233
- }
234
-
235
- return response.user;
236
- } catch (error: any) {
237
- const errorMessage = error.message || 'Registration failed';
238
- setError(errorMessage);
239
- throw new Error(errorMessage);
240
- } finally {
241
- setIsLoading(false);
242
- }
243
- }, [api, saveToStorage, onAuthChange]);
244
-
245
- const contextValue: OxyZeroConfigState = {
246
- user,
247
- isAuthenticated,
248
- isLoading,
249
- error,
250
- login,
251
- logout,
252
- register,
253
- api
254
- };
255
-
256
- return (
257
- <OxyZeroConfigContext.Provider value={contextValue}>
258
- {children}
259
- </OxyZeroConfigContext.Provider>
260
- );
261
- };
262
-
263
- /**
264
- * Zero-config hook for OxyHQ Services
265
- *
266
- * @example
267
- * ```tsx
268
- * function MyComponent() {
269
- * const { user, login, logout, isAuthenticated } = useOxyZeroConfig();
270
- *
271
- * const handleLogin = () => {
272
- * login('username', 'password');
273
- * };
274
- *
275
- * if (isAuthenticated) {
276
- * return <div>Welcome, {user?.username}!</div>;
277
- * }
278
- *
279
- * return <button onClick={handleLogin}>Login</button>;
280
- * }
281
- * ```
282
- */
283
- export const useOxyZeroConfig = (): OxyZeroConfigState => {
284
- const context = useContext(OxyZeroConfigContext);
285
- if (!context) {
286
- throw new Error('useOxyZeroConfig must be used within an OxyZeroConfigProvider');
287
- }
288
- return context;
289
- };
290
-
291
- /**
292
- * Hook for automatic API client with authentication
293
- * This automatically includes the auth token in requests
294
- *
295
- * @example
296
- * ```tsx
297
- * function ProfileComponent() {
298
- * const api = useOxyApi();
299
- *
300
- * const updateProfile = async (data) => {
301
- * const user = await api.updateProfile(data);
302
- * // Token is automatically included
303
- * };
304
- * }
305
- * ```
306
- */
307
- export const useOxyApi = (): OxyServices => {
308
- const { api } = useOxyZeroConfig();
309
- return api;
310
- };