@symbo.ls/sdk 3.2.3 → 3.2.7

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 (183) hide show
  1. package/README.md +141 -0
  2. package/dist/cjs/config/environment.js +94 -10
  3. package/dist/cjs/index.js +152 -12
  4. package/dist/cjs/services/AdminService.js +351 -0
  5. package/dist/cjs/services/AuthService.js +738 -305
  6. package/dist/cjs/services/BaseService.js +158 -6
  7. package/dist/cjs/services/BranchService.js +484 -0
  8. package/dist/cjs/services/CollabService.js +439 -116
  9. package/dist/cjs/services/DnsService.js +340 -0
  10. package/dist/cjs/services/FeatureFlagService.js +175 -0
  11. package/dist/cjs/services/FileService.js +201 -0
  12. package/dist/cjs/services/IntegrationService.js +538 -0
  13. package/dist/cjs/services/MetricsService.js +62 -0
  14. package/dist/cjs/services/PaymentService.js +271 -0
  15. package/dist/cjs/services/PlanService.js +426 -0
  16. package/dist/cjs/services/ProjectService.js +1207 -0
  17. package/dist/cjs/services/PullRequestService.js +503 -0
  18. package/dist/cjs/services/ScreenshotService.js +304 -0
  19. package/dist/cjs/services/SubscriptionService.js +396 -0
  20. package/dist/cjs/services/TrackingService.js +661 -0
  21. package/dist/cjs/services/WaitlistService.js +148 -0
  22. package/dist/cjs/services/index.js +60 -4
  23. package/dist/cjs/state/RootStateManager.js +2 -23
  24. package/dist/cjs/state/rootEventBus.js +9 -0
  25. package/dist/cjs/utils/CollabClient.js +78 -12
  26. package/dist/cjs/utils/TokenManager.js +16 -3
  27. package/dist/cjs/utils/changePreprocessor.js +199 -0
  28. package/dist/cjs/utils/jsonDiff.js +46 -4
  29. package/dist/cjs/utils/ordering.js +309 -0
  30. package/dist/cjs/utils/services.js +285 -128
  31. package/dist/cjs/utils/validation.js +0 -3
  32. package/dist/esm/config/environment.js +94 -10
  33. package/dist/esm/index.js +47862 -18248
  34. package/dist/esm/services/AdminService.js +1132 -0
  35. package/dist/esm/services/AuthService.js +1493 -386
  36. package/dist/esm/services/BaseService.js +757 -6
  37. package/dist/esm/services/BranchService.js +1265 -0
  38. package/dist/esm/services/CollabService.js +24956 -16089
  39. package/dist/esm/services/DnsService.js +1121 -0
  40. package/dist/esm/services/FeatureFlagService.js +956 -0
  41. package/dist/esm/services/FileService.js +982 -0
  42. package/dist/esm/services/IntegrationService.js +1319 -0
  43. package/dist/esm/services/MetricsService.js +843 -0
  44. package/dist/esm/services/PaymentService.js +1052 -0
  45. package/dist/esm/services/PlanService.js +1207 -0
  46. package/dist/esm/services/ProjectService.js +2526 -0
  47. package/dist/esm/services/PullRequestService.js +1284 -0
  48. package/dist/esm/services/ScreenshotService.js +1085 -0
  49. package/dist/esm/services/SubscriptionService.js +1177 -0
  50. package/dist/esm/services/TrackingService.js +18454 -0
  51. package/dist/esm/services/WaitlistService.js +929 -0
  52. package/dist/esm/services/index.js +47373 -18027
  53. package/dist/esm/state/RootStateManager.js +11 -23
  54. package/dist/esm/state/rootEventBus.js +9 -0
  55. package/dist/esm/utils/CollabClient.js +17526 -16120
  56. package/dist/esm/utils/TokenManager.js +16 -3
  57. package/dist/esm/utils/changePreprocessor.js +542 -0
  58. package/dist/esm/utils/jsonDiff.js +958 -43
  59. package/dist/esm/utils/ordering.js +291 -0
  60. package/dist/esm/utils/services.js +285 -128
  61. package/dist/esm/utils/validation.js +116 -50
  62. package/dist/node/config/environment.js +94 -10
  63. package/dist/node/index.js +183 -16
  64. package/dist/node/services/AdminService.js +332 -0
  65. package/dist/node/services/AuthService.js +742 -310
  66. package/dist/node/services/BaseService.js +148 -6
  67. package/dist/node/services/BranchService.js +465 -0
  68. package/dist/node/services/CollabService.js +439 -116
  69. package/dist/node/services/DnsService.js +321 -0
  70. package/dist/node/services/FeatureFlagService.js +156 -0
  71. package/dist/node/services/FileService.js +182 -0
  72. package/dist/node/services/IntegrationService.js +519 -0
  73. package/dist/node/services/MetricsService.js +43 -0
  74. package/dist/node/services/PaymentService.js +252 -0
  75. package/dist/node/services/PlanService.js +407 -0
  76. package/dist/node/services/ProjectService.js +1188 -0
  77. package/dist/node/services/PullRequestService.js +484 -0
  78. package/dist/node/services/ScreenshotService.js +285 -0
  79. package/dist/node/services/SubscriptionService.js +377 -0
  80. package/dist/node/services/TrackingService.js +632 -0
  81. package/dist/node/services/WaitlistService.js +129 -0
  82. package/dist/node/services/index.js +60 -4
  83. package/dist/node/state/RootStateManager.js +2 -23
  84. package/dist/node/state/rootEventBus.js +9 -0
  85. package/dist/node/utils/CollabClient.js +77 -11
  86. package/dist/node/utils/TokenManager.js +16 -3
  87. package/dist/node/utils/changePreprocessor.js +180 -0
  88. package/dist/node/utils/jsonDiff.js +46 -4
  89. package/dist/node/utils/ordering.js +290 -0
  90. package/dist/node/utils/services.js +285 -128
  91. package/dist/node/utils/validation.js +0 -3
  92. package/package.json +30 -18
  93. package/src/config/environment.js +95 -10
  94. package/src/index.js +190 -23
  95. package/src/services/AdminService.js +374 -0
  96. package/src/services/AuthService.js +874 -328
  97. package/src/services/BaseService.js +166 -6
  98. package/src/services/BranchService.js +536 -0
  99. package/src/services/CollabService.js +557 -148
  100. package/src/services/DnsService.js +366 -0
  101. package/src/services/FeatureFlagService.js +174 -0
  102. package/src/services/FileService.js +213 -0
  103. package/src/services/IntegrationService.js +548 -0
  104. package/src/services/MetricsService.js +40 -0
  105. package/src/services/PaymentService.js +287 -0
  106. package/src/services/PlanService.js +468 -0
  107. package/src/services/ProjectService.js +1366 -0
  108. package/src/services/PullRequestService.js +537 -0
  109. package/src/services/ScreenshotService.js +258 -0
  110. package/src/services/SubscriptionService.js +425 -0
  111. package/src/services/TrackingService.js +853 -0
  112. package/src/services/WaitlistService.js +130 -0
  113. package/src/services/index.js +79 -5
  114. package/src/services/tests/BranchService/createBranch.test.js +153 -0
  115. package/src/services/tests/BranchService/deleteBranch.test.js +173 -0
  116. package/src/services/tests/BranchService/getBranchChanges.test.js +146 -0
  117. package/src/services/tests/BranchService/listBranches.test.js +87 -0
  118. package/src/services/tests/BranchService/mergeBranch.test.js +210 -0
  119. package/src/services/tests/BranchService/publishVersion.test.js +183 -0
  120. package/src/services/tests/BranchService/renameBranch.test.js +240 -0
  121. package/src/services/tests/BranchService/resetBranch.test.js +152 -0
  122. package/src/services/tests/FeatureFlagService/adminFeatureFlags.test.js +67 -0
  123. package/src/services/tests/FeatureFlagService/getFeatureFlags.test.js +75 -0
  124. package/src/services/tests/FileService/createFileFormData.test.js +74 -0
  125. package/src/services/tests/FileService/getFileUrl.test.js +69 -0
  126. package/src/services/tests/FileService/updateProjectIcon.test.js +109 -0
  127. package/src/services/tests/FileService/uploadDocument.test.js +36 -0
  128. package/src/services/tests/FileService/uploadFile.test.js +78 -0
  129. package/src/services/tests/FileService/uploadFileWithValidation.test.js +114 -0
  130. package/src/services/tests/FileService/uploadImage.test.js +36 -0
  131. package/src/services/tests/FileService/uploadMultipleFiles.test.js +111 -0
  132. package/src/services/tests/FileService/validateFile.test.js +63 -0
  133. package/src/services/tests/PlanService/createPlan.test.js +104 -0
  134. package/src/services/tests/PlanService/createPlanWithValidation.test.js +523 -0
  135. package/src/services/tests/PlanService/deletePlan.test.js +92 -0
  136. package/src/services/tests/PlanService/getActivePlans.test.js +123 -0
  137. package/src/services/tests/PlanService/getAdminPlans.test.js +84 -0
  138. package/src/services/tests/PlanService/getPlan.test.js +50 -0
  139. package/src/services/tests/PlanService/getPlanByKey.test.js +109 -0
  140. package/src/services/tests/PlanService/getPlanWithValidation.test.js +85 -0
  141. package/src/services/tests/PlanService/getPlans.test.js +53 -0
  142. package/src/services/tests/PlanService/getPlansByPriceRange.test.js +109 -0
  143. package/src/services/tests/PlanService/getPlansWithValidation.test.js +48 -0
  144. package/src/services/tests/PlanService/initializePlans.test.js +75 -0
  145. package/src/services/tests/PlanService/updatePlan.test.js +111 -0
  146. package/src/services/tests/PlanService/updatePlanWithValidation.test.js +556 -0
  147. package/src/state/RootStateManager.js +37 -32
  148. package/src/state/rootEventBus.js +19 -0
  149. package/src/utils/CollabClient.js +99 -12
  150. package/src/utils/TokenManager.js +20 -3
  151. package/src/utils/changePreprocessor.js +239 -0
  152. package/src/utils/jsonDiff.js +40 -5
  153. package/src/utils/ordering.js +271 -0
  154. package/src/utils/services.js +306 -139
  155. package/src/utils/validation.js +0 -3
  156. package/dist/cjs/services/AIService.js +0 -155
  157. package/dist/cjs/services/BasedService.js +0 -1185
  158. package/dist/cjs/services/CoreService.js +0 -2295
  159. package/dist/cjs/services/SocketService.js +0 -309
  160. package/dist/cjs/services/SymstoryService.js +0 -571
  161. package/dist/cjs/utils/basedQuerys.js +0 -181
  162. package/dist/cjs/utils/symstoryClient.js +0 -259
  163. package/dist/esm/services/AIService.js +0 -185
  164. package/dist/esm/services/BasedService.js +0 -5262
  165. package/dist/esm/services/CoreService.js +0 -2827
  166. package/dist/esm/services/SocketService.js +0 -456
  167. package/dist/esm/services/SymstoryService.js +0 -7025
  168. package/dist/esm/utils/basedQuerys.js +0 -163
  169. package/dist/esm/utils/symstoryClient.js +0 -354
  170. package/dist/node/services/AIService.js +0 -136
  171. package/dist/node/services/BasedService.js +0 -1156
  172. package/dist/node/services/CoreService.js +0 -2266
  173. package/dist/node/services/SocketService.js +0 -280
  174. package/dist/node/services/SymstoryService.js +0 -542
  175. package/dist/node/utils/basedQuerys.js +0 -162
  176. package/dist/node/utils/symstoryClient.js +0 -230
  177. package/src/services/AIService.js +0 -150
  178. package/src/services/BasedService.js +0 -1302
  179. package/src/services/CoreService.js +0 -2548
  180. package/src/services/SocketService.js +0 -336
  181. package/src/services/SymstoryService.js +0 -649
  182. package/src/utils/basedQuerys.js +0 -164
  183. package/src/utils/symstoryClient.js +0 -252
@@ -22,187 +22,742 @@ __export(AuthService_exports, {
22
22
  module.exports = __toCommonJS(AuthService_exports);
23
23
  var import_BaseService = require("./BaseService.js");
24
24
  var import_permission = require("../utils/permission.js");
25
+ const PLUGIN_SESSION_STORAGE_KEY = "plugin_auth_session";
25
26
  class AuthService extends import_BaseService.BaseService {
26
27
  constructor(config) {
28
+ var _a, _b;
27
29
  super(config);
28
30
  this._userRoles = /* @__PURE__ */ new Set(["guest", "editor", "admin", "owner"]);
29
31
  this._projectTiers = /* @__PURE__ */ new Set([
30
32
  "ready",
31
- "free",
33
+ "starter",
32
34
  "pro1",
33
35
  "pro2",
34
36
  "enterprise"
35
37
  ]);
36
- this._initialized = false;
38
+ this._projectRoleCache = /* @__PURE__ */ new Map();
39
+ this._roleCacheExpiry = 5 * 60 * 1e3;
40
+ this._pluginSession = null;
41
+ this._resolvePluginSession(
42
+ (config == null ? void 0 : config.session) || (config == null ? void 0 : config.pluginSession) || ((_a = config == null ? void 0 : config.options) == null ? void 0 : _a.pluginSession) || ((_b = config == null ? void 0 : config.context) == null ? void 0 : _b.pluginSession) || null
43
+ );
37
44
  }
38
- // eslint-disable-next-line no-empty-pattern
39
- init({}) {
45
+ // Use BaseService.init/_request/_requireReady implementations
46
+ // ==================== AUTH METHODS ====================
47
+ async register(userData, options = {}) {
40
48
  try {
41
- const { authToken, appKey } = this._context || {};
42
- this._info = {
43
- config: {
44
- appKey: appKey ? `${appKey.substr(0, 4)}...${appKey.substr(-4)}` : void 0,
45
- // eslint-disable-line no-undefined
46
- hasToken: Boolean(authToken)
49
+ const { payload, session } = this._preparePluginPayload(
50
+ { ...userData || {} },
51
+ options.session
52
+ );
53
+ const response = await this._request("/auth/register", {
54
+ method: "POST",
55
+ body: JSON.stringify(payload),
56
+ methodName: "register"
57
+ });
58
+ if (response.success) {
59
+ if (session) {
60
+ this._clearPluginSession(session);
47
61
  }
48
- };
49
- this._initialized = true;
50
- this._setReady();
62
+ return response.data;
63
+ }
64
+ throw new Error(response.message);
51
65
  } catch (error) {
52
- this._setError(error);
53
- throw error;
54
- }
55
- }
56
- _requiresInit(methodName) {
57
- const noInitMethods = /* @__PURE__ */ new Set([
58
- "users:login",
59
- "users:register",
60
- "users:request-password-reset",
61
- "users:reset-password",
62
- "users:reset-password-confirm",
63
- "users:register-confirmation",
64
- "users:google-auth",
65
- "users:github-auth"
66
- ]);
67
- return !noInitMethods.has(methodName);
66
+ throw new Error(`Registration failed: ${error.message}`, { cause: error });
67
+ }
68
68
  }
69
- _requireReady(methodName) {
70
- if (this._requiresInit(methodName) && !this._initialized) {
71
- throw new Error("Service not initialized");
69
+ async login(email, password, options = {}) {
70
+ var _a;
71
+ try {
72
+ const { payload, session } = this._preparePluginPayload(
73
+ {
74
+ email,
75
+ password
76
+ },
77
+ options.session
78
+ );
79
+ const response = await this._request("/auth/login", {
80
+ method: "POST",
81
+ body: JSON.stringify(payload),
82
+ methodName: "login"
83
+ });
84
+ if (response.success && response.data && response.data.tokens) {
85
+ const { tokens } = response.data;
86
+ const tokenData = {
87
+ access_token: tokens.accessToken,
88
+ refresh_token: tokens.refreshToken,
89
+ expires_in: (_a = tokens.accessTokenExp) == null ? void 0 : _a.expiresIn,
90
+ token_type: "Bearer"
91
+ };
92
+ if (this._tokenManager) {
93
+ this._tokenManager.setTokens(tokenData);
94
+ }
95
+ }
96
+ if (response.success) {
97
+ if (session) {
98
+ this._clearPluginSession(session);
99
+ }
100
+ return response.data;
101
+ }
102
+ throw new Error(response.message);
103
+ } catch (error) {
104
+ throw new Error(`Login failed: ${error.message}`, { cause: error });
72
105
  }
73
106
  }
74
- _getBasedService(methodName) {
107
+ async logout() {
108
+ this._requireReady("logout");
109
+ try {
110
+ await this._request("/auth/logout", {
111
+ method: "POST",
112
+ methodName: "logout"
113
+ });
114
+ if (this._tokenManager) {
115
+ this._tokenManager.clearTokens();
116
+ }
117
+ } catch (error) {
118
+ if (this._tokenManager) {
119
+ this._tokenManager.clearTokens();
120
+ }
121
+ throw new Error(`Logout failed: ${error.message}`, { cause: error });
122
+ }
123
+ }
124
+ async refreshToken(refreshToken) {
125
+ try {
126
+ const response = await this._request("/auth/refresh", {
127
+ method: "POST",
128
+ body: JSON.stringify({ refreshToken }),
129
+ methodName: "refreshToken"
130
+ });
131
+ if (response.success) {
132
+ return response.data;
133
+ }
134
+ throw new Error(response.message);
135
+ } catch (error) {
136
+ throw new Error(`Token refresh failed: ${error.message}`, { cause: error });
137
+ }
138
+ }
139
+ async googleAuth(idToken, inviteToken = null, options = {}) {
75
140
  var _a;
76
- const based = (_a = this._context.services) == null ? void 0 : _a.based;
77
- if (this._requiresInit(methodName) && !based) {
78
- throw new Error("Based service not available");
141
+ try {
142
+ const { payload, session } = this._preparePluginPayload({ idToken }, options.session);
143
+ if (inviteToken) {
144
+ payload.inviteToken = inviteToken;
145
+ }
146
+ const response = await this._request("/auth/google", {
147
+ method: "POST",
148
+ body: JSON.stringify(payload),
149
+ methodName: "googleAuth"
150
+ });
151
+ if (response.success && response.data && response.data.tokens) {
152
+ const { tokens } = response.data;
153
+ const tokenData = {
154
+ access_token: tokens.accessToken,
155
+ refresh_token: tokens.refreshToken,
156
+ expires_in: (_a = tokens.accessTokenExp) == null ? void 0 : _a.expiresIn,
157
+ token_type: "Bearer"
158
+ };
159
+ if (this._tokenManager) {
160
+ this._tokenManager.setTokens(tokenData);
161
+ }
162
+ }
163
+ if (response.success) {
164
+ if (session) {
165
+ this._clearPluginSession(session);
166
+ }
167
+ return response.data;
168
+ }
169
+ throw new Error(response.message);
170
+ } catch (error) {
171
+ throw new Error(`Google auth failed: ${error.message}`, { cause: error });
79
172
  }
80
- return based._client;
81
173
  }
82
- async login(identifier, password) {
174
+ async githubAuth(code, inviteToken = null, options = {}) {
175
+ var _a;
83
176
  try {
84
- const based = this._getBasedService("login");
85
- const response = await based.call("users:login", { identifier, password });
86
- if (this._initialized) {
87
- this.updateContext({ authToken: response.token });
88
- }
89
- based.setAuthState({
90
- token: response.token,
91
- userId: response.userId,
92
- projectRoles: response.projectRoles,
93
- globalRole: response.globalRole,
94
- persistent: true
177
+ const { payload, session } = this._preparePluginPayload({ code }, options.session);
178
+ if (inviteToken) {
179
+ payload.inviteToken = inviteToken;
180
+ }
181
+ const response = await this._request("/auth/github", {
182
+ method: "POST",
183
+ body: JSON.stringify(payload),
184
+ methodName: "githubAuth"
95
185
  });
96
- return response;
186
+ if (response.success && response.data && response.data.tokens) {
187
+ const { tokens } = response.data;
188
+ const tokenData = {
189
+ access_token: tokens.accessToken,
190
+ refresh_token: tokens.refreshToken,
191
+ expires_in: (_a = tokens.accessTokenExp) == null ? void 0 : _a.expiresIn,
192
+ token_type: "Bearer"
193
+ };
194
+ if (this._tokenManager) {
195
+ this._tokenManager.setTokens(tokenData);
196
+ }
197
+ }
198
+ if (response.success) {
199
+ if (session) {
200
+ this._clearPluginSession(session);
201
+ }
202
+ return response.data;
203
+ }
204
+ throw new Error(response.message);
97
205
  } catch (error) {
98
- throw new Error(`Login failed: ${error.message}`);
206
+ throw new Error(`GitHub auth failed: ${error.message}`, { cause: error });
99
207
  }
100
208
  }
101
- async register(userData) {
209
+ async googleAuthCallback(code, redirectUri, inviteToken = null, options = {}) {
210
+ var _a;
102
211
  try {
103
- const based = this._getBasedService("register");
104
- return await based.call("users:register", userData);
212
+ const { payload: body, session } = this._preparePluginPayload(
213
+ { code, redirectUri },
214
+ options.session
215
+ );
216
+ if (inviteToken) {
217
+ body.inviteToken = inviteToken;
218
+ }
219
+ const response = await this._request("/auth/google/callback", {
220
+ method: "POST",
221
+ body: JSON.stringify(body),
222
+ methodName: "googleAuthCallback"
223
+ });
224
+ if (response.success && response.data && response.data.tokens) {
225
+ const { tokens } = response.data;
226
+ const tokenData = {
227
+ access_token: tokens.accessToken,
228
+ refresh_token: tokens.refreshToken,
229
+ expires_in: (_a = tokens.accessTokenExp) == null ? void 0 : _a.expiresIn,
230
+ token_type: "Bearer"
231
+ };
232
+ if (this._tokenManager) {
233
+ this._tokenManager.setTokens(tokenData);
234
+ }
235
+ }
236
+ if (response.success) {
237
+ if (session) {
238
+ this._clearPluginSession(session);
239
+ }
240
+ return response.data;
241
+ }
242
+ throw new Error(response.message);
105
243
  } catch (error) {
106
- throw new Error(`Registration failed: ${error.message}`);
244
+ throw new Error(`Google auth callback failed: ${error.message}`, { cause: error });
107
245
  }
108
246
  }
109
- async googleAuth(idToken) {
247
+ async requestPasswordReset(email) {
110
248
  try {
111
- const based = this._getBasedService("googleAuth");
112
- const response = await based.call("users:google-auth", { idToken });
113
- if (this._initialized) {
114
- this.updateContext({ authToken: response.token });
115
- }
116
- based.setAuthState({
117
- token: response.token,
118
- userId: response.userId,
119
- persistent: true
249
+ const response = await this._request("/auth/request-password-reset", {
250
+ method: "POST",
251
+ body: JSON.stringify({ email }),
252
+ methodName: "requestPasswordReset"
120
253
  });
121
- return response;
254
+ if (response.success) {
255
+ return response.data;
256
+ }
257
+ throw new Error(response.message);
122
258
  } catch (error) {
123
- throw new Error(`Google auth failed: ${error.message}`);
259
+ throw new Error(`Password reset request failed: ${error.message}`, { cause: error });
124
260
  }
125
261
  }
126
- async googleAuthCallback(code, redirectUri) {
262
+ async confirmPasswordReset(token, password) {
127
263
  try {
128
- const based = this._getBasedService("googleAuthCallback");
129
- const response = await based.call("users:google-auth-callback", {
130
- code,
131
- redirectUri
264
+ const response = await this._request("/auth/reset-password-confirm", {
265
+ method: "POST",
266
+ body: JSON.stringify({ token, password }),
267
+ methodName: "confirmPasswordReset"
132
268
  });
133
- if (this._initialized) {
134
- this.updateContext({ authToken: response.token });
269
+ if (response.success) {
270
+ return response.data;
135
271
  }
136
- based.setAuthState({
137
- token: response.token,
138
- userId: response.userId,
139
- persistent: true
272
+ throw new Error(response.message);
273
+ } catch (error) {
274
+ throw new Error(`Password reset confirmation failed: ${error.message}`, { cause: error });
275
+ }
276
+ }
277
+ async confirmRegistration(token) {
278
+ try {
279
+ const response = await this._request("/auth/register-confirmation", {
280
+ method: "POST",
281
+ body: JSON.stringify({ token }),
282
+ methodName: "confirmRegistration"
140
283
  });
141
- return response;
284
+ if (response.success) {
285
+ return response.data;
286
+ }
287
+ throw new Error(response.message);
142
288
  } catch (error) {
143
- throw new Error(`Google auth callback failed: ${error.message}`);
289
+ throw new Error(`Registration confirmation failed: ${error.message}`, { cause: error });
144
290
  }
145
291
  }
146
- async githubAuth(code) {
292
+ async requestPasswordChange() {
293
+ this._requireReady("requestPasswordChange");
147
294
  try {
148
- const based = this._getBasedService("githubAuth");
149
- const response = await based.call("users:github-auth", { code });
150
- if (this._initialized) {
151
- this.updateContext({ authToken: response.token });
152
- }
153
- based.setAuthState({
154
- token: response.token,
155
- userId: response.userId,
156
- persistent: true
295
+ const response = await this._request("/auth/request-password-change", {
296
+ method: "POST",
297
+ methodName: "requestPasswordChange"
157
298
  });
158
- return response;
299
+ if (response.success) {
300
+ return response.data;
301
+ }
302
+ throw new Error(response.message);
159
303
  } catch (error) {
160
- throw new Error(`GitHub auth failed: ${error.message}`);
304
+ throw new Error(`Password change request failed: ${error.message}`, { cause: error });
161
305
  }
162
306
  }
163
- async logout() {
164
- this._requireReady("logout");
307
+ async confirmPasswordChange(currentPassword, newPassword, code) {
308
+ this._requireReady("confirmPasswordChange");
165
309
  try {
166
- const based = this._getBasedService("logout");
167
- await based.call("users:logout");
168
- this.updateContext({ authToken: null });
310
+ const response = await this._request("/auth/confirm-password-change", {
311
+ method: "POST",
312
+ body: JSON.stringify({ currentPassword, newPassword, code }),
313
+ methodName: "confirmPasswordChange"
314
+ });
315
+ if (response.success) {
316
+ return response.data;
317
+ }
318
+ throw new Error(response.message);
169
319
  } catch (error) {
170
- throw new Error(`Logout failed: ${error.message}`);
320
+ throw new Error(`Password change confirmation failed: ${error.message}`, { cause: error });
321
+ }
322
+ }
323
+ async getMe(options = {}) {
324
+ this._requireReady("getMe");
325
+ try {
326
+ const session = this._resolvePluginSession(options.session);
327
+ const endpoint = session ? `/auth/me?session=${encodeURIComponent(session)}` : "/auth/me";
328
+ const response = await this._request(endpoint, {
329
+ method: "GET",
330
+ methodName: "getMe"
331
+ });
332
+ if (response.success) {
333
+ return response.data;
334
+ }
335
+ throw new Error(response.message);
336
+ } catch (error) {
337
+ throw new Error(`Failed to get user profile: ${error.message}`, { cause: error });
338
+ }
339
+ }
340
+ getAuthToken() {
341
+ if (!this._tokenManager) {
342
+ return null;
171
343
  }
344
+ return this._tokenManager.getAccessToken();
172
345
  }
173
- async updateUserRole(userId, newRole) {
174
- this._requireReady("updateUserRole");
346
+ /**
347
+ * Get stored authentication state (backward compatibility method)
348
+ * Replaces AuthService.getStoredAuthState()
349
+ */
350
+ async getStoredAuthState() {
351
+ try {
352
+ if (!this._tokenManager) {
353
+ return {
354
+ userId: false,
355
+ authToken: false
356
+ };
357
+ }
358
+ const tokenStatus = this._tokenManager.getTokenStatus();
359
+ if (!tokenStatus.hasTokens) {
360
+ return {
361
+ userId: false,
362
+ authToken: false
363
+ };
364
+ }
365
+ if (!tokenStatus.isValid && tokenStatus.hasRefreshToken) {
366
+ try {
367
+ await this._tokenManager.ensureValidToken();
368
+ } catch (error) {
369
+ console.warn("[AuthService] Token refresh failed:", error.message);
370
+ if (error.message.includes("401") || error.message.includes("403") || error.message.includes("invalid") || error.message.includes("expired")) {
371
+ this._tokenManager.clearTokens();
372
+ return {
373
+ userId: false,
374
+ authToken: false,
375
+ error: `Authentication failed: ${error.message}`
376
+ };
377
+ }
378
+ return {
379
+ userId: false,
380
+ authToken: this._tokenManager.getAccessToken(),
381
+ error: `Network error during token refresh: ${error.message}`,
382
+ hasTokens: true
383
+ };
384
+ }
385
+ }
386
+ const currentAccessToken = this._tokenManager.getAccessToken();
387
+ if (!currentAccessToken) {
388
+ return {
389
+ userId: false,
390
+ authToken: false
391
+ };
392
+ }
393
+ try {
394
+ const currentUser = await this.getMe();
395
+ return {
396
+ userId: currentUser.user.id,
397
+ authToken: currentAccessToken,
398
+ ...currentUser,
399
+ error: null
400
+ };
401
+ } catch (error) {
402
+ console.warn("[AuthService] Failed to get user data:", error.message);
403
+ if (error.message.includes("401") || error.message.includes("403")) {
404
+ this._tokenManager.clearTokens();
405
+ return {
406
+ userId: false,
407
+ authToken: false,
408
+ error: `Authentication failed: ${error.message}`
409
+ };
410
+ }
411
+ return {
412
+ userId: false,
413
+ authToken: currentAccessToken,
414
+ error: `Failed to get user data: ${error.message}`,
415
+ hasTokens: true
416
+ };
417
+ }
418
+ } catch (error) {
419
+ console.error(
420
+ "[AuthService] Unexpected error in getStoredAuthState:",
421
+ error
422
+ );
423
+ return {
424
+ userId: false,
425
+ authToken: false,
426
+ error: `Failed to get stored auth state: ${error.message}`
427
+ };
428
+ }
429
+ }
430
+ // ==================== USER METHODS ====================
431
+ async getUserProfile() {
432
+ this._requireReady("getUserProfile");
433
+ try {
434
+ const response = await this._request("/users/profile", {
435
+ method: "GET",
436
+ methodName: "getUserProfile"
437
+ });
438
+ if (response.success) {
439
+ return response.data;
440
+ }
441
+ throw new Error(response.message);
442
+ } catch (error) {
443
+ throw new Error(`Failed to get user profile: ${error.message}`, { cause: error });
444
+ }
445
+ }
446
+ async updateUserProfile(profileData) {
447
+ this._requireReady("updateUserProfile");
448
+ try {
449
+ const response = await this._request("/users/profile", {
450
+ method: "PATCH",
451
+ body: JSON.stringify(profileData),
452
+ methodName: "updateUserProfile"
453
+ });
454
+ if (response.success) {
455
+ return response.data;
456
+ }
457
+ throw new Error(response.message);
458
+ } catch (error) {
459
+ throw new Error(`Failed to update user profile: ${error.message}`, { cause: error });
460
+ }
461
+ }
462
+ async getUserProjects() {
463
+ this._requireReady("getUserProjects");
464
+ try {
465
+ const response = await this._request("/users/projects", {
466
+ method: "GET",
467
+ methodName: "getUserProjects"
468
+ });
469
+ if (response.success) {
470
+ return response.data.map((project) => ({
471
+ ...project,
472
+ ...project.icon && {
473
+ icon: {
474
+ src: `${this._apiUrl}/core/files/public/${project.icon.id}/download`,
475
+ ...project.icon
476
+ }
477
+ }
478
+ }));
479
+ }
480
+ throw new Error(response.message);
481
+ } catch (error) {
482
+ throw new Error(`Failed to get user projects: ${error.message}`, { cause: error });
483
+ }
484
+ }
485
+ async getUser(userId) {
486
+ this._requireReady("getUser");
175
487
  if (!userId) {
176
488
  throw new Error("User ID is required");
177
489
  }
178
- if (!this._userRoles.has(newRole)) {
179
- throw new Error(`Invalid role: ${newRole}`);
490
+ try {
491
+ const response = await this._request(`/users/${userId}`, {
492
+ method: "GET",
493
+ methodName: "getUser"
494
+ });
495
+ if (response.success) {
496
+ return response.data;
497
+ }
498
+ throw new Error(response.message);
499
+ } catch (error) {
500
+ throw new Error(`Failed to get user: ${error.message}`, { cause: error });
501
+ }
502
+ }
503
+ async getUserByEmail(email) {
504
+ this._requireReady("getUserByEmail");
505
+ if (!email) {
506
+ throw new Error("Email is required");
180
507
  }
181
508
  try {
182
- const based = this._getBasedService("updateUserRole");
183
- return await based.call("users:update-role", { userId, role: newRole });
509
+ const response = await this._request(`/auth/user?email=${email}`, {
510
+ method: "GET",
511
+ methodName: "getUserByEmail"
512
+ });
513
+ if (response.success) {
514
+ return response.data.user;
515
+ }
516
+ throw new Error(response.message);
184
517
  } catch (error) {
185
- throw new Error(`Failed to update user role: ${error.message}`);
518
+ throw new Error(`Failed to get user by email: ${error.message}`, { cause: error });
186
519
  }
187
520
  }
188
- async updateProjectTier(projectId, newTier) {
189
- this._requireReady("updateProjectTier");
521
+ // ==================== PROJECT ROLE METHODS ====================
522
+ /**
523
+ * Get the current user's role for a specific project by project ID
524
+ * Uses caching to avoid repeated API calls
525
+ */
526
+ async getMyProjectRole(projectId) {
527
+ this._requireReady("getMyProjectRole");
190
528
  if (!projectId) {
191
529
  throw new Error("Project ID is required");
192
530
  }
193
- if (!this._projectTiers.has(newTier)) {
194
- throw new Error(`Invalid project tier: ${newTier}`);
531
+ if (!this.hasValidTokens()) {
532
+ return "guest";
533
+ }
534
+ const cacheKey = `role_${projectId}`;
535
+ const cached = this._projectRoleCache.get(cacheKey);
536
+ if (cached && Date.now() - cached.timestamp < this._roleCacheExpiry) {
537
+ return cached.role;
538
+ }
539
+ try {
540
+ const response = await this._request(`/projects/${projectId}/role`, {
541
+ method: "GET",
542
+ methodName: "getMyProjectRole"
543
+ });
544
+ if (response.success) {
545
+ const { role } = response.data;
546
+ this._projectRoleCache.set(cacheKey, {
547
+ role,
548
+ timestamp: Date.now()
549
+ });
550
+ return role;
551
+ }
552
+ throw new Error(response.message);
553
+ } catch (error) {
554
+ const message = (error == null ? void 0 : error.message) || "";
555
+ if (/401|403|unauthorized|no token|invalid token/iu.test(message)) {
556
+ return "guest";
557
+ }
558
+ throw new Error(`Failed to get project role: ${message}`, { cause: error });
559
+ }
560
+ }
561
+ /**
562
+ * Get the current user's role for a specific project by project key
563
+ * Uses caching to avoid repeated API calls
564
+ */
565
+ async getMyProjectRoleByKey(projectKey) {
566
+ this._requireReady("getMyProjectRoleByKey");
567
+ if (!projectKey) {
568
+ throw new Error("Project key is required");
569
+ }
570
+ if (!this.hasValidTokens()) {
571
+ return "guest";
572
+ }
573
+ const cacheKey = `role_key_${projectKey}`;
574
+ const cached = this._projectRoleCache.get(cacheKey);
575
+ if (cached && Date.now() - cached.timestamp < this._roleCacheExpiry) {
576
+ return cached.role;
195
577
  }
196
578
  try {
197
- const based = this._getBasedService("updateProjectTier");
198
- return await based.call("projects:update-tier", {
199
- projectId,
200
- tier: newTier
579
+ const response = await this._request(`/projects/key/${projectKey}/role`, {
580
+ method: "GET",
581
+ methodName: "getMyProjectRoleByKey"
201
582
  });
583
+ if (response.success) {
584
+ const { role } = response.data;
585
+ this._projectRoleCache.set(cacheKey, {
586
+ role,
587
+ timestamp: Date.now()
588
+ });
589
+ return role;
590
+ }
591
+ throw new Error(response.message);
202
592
  } catch (error) {
203
- throw new Error(`Failed to update project tier: ${error.message}`);
593
+ const message = (error == null ? void 0 : error.message) || "";
594
+ if (/401|403|unauthorized|no token|invalid token/iu.test(message)) {
595
+ return "guest";
596
+ }
597
+ throw new Error(`Failed to get project role by key: ${message}`, { cause: error });
598
+ }
599
+ }
600
+ /**
601
+ * Clear the project role cache for a specific project or all projects
602
+ */
603
+ clearProjectRoleCache(projectId = null) {
604
+ if (projectId) {
605
+ this._projectRoleCache.delete(`role_${projectId}`);
606
+ for (const [key] of this._projectRoleCache) {
607
+ if (key.startsWith("role_key_")) {
608
+ this._projectRoleCache.delete(key);
609
+ }
610
+ }
611
+ } else {
612
+ this._projectRoleCache.clear();
613
+ }
614
+ }
615
+ /**
616
+ * Get project role with fallback to user projects list
617
+ * This method tries to get the role from user projects first,
618
+ * then falls back to API call if not found
619
+ */
620
+ async getProjectRoleWithFallback(projectId, userProjects = null) {
621
+ this._requireReady("getProjectRoleWithFallback");
622
+ if (!projectId) {
623
+ throw new Error("Project ID is required");
624
+ }
625
+ if (userProjects && Array.isArray(userProjects)) {
626
+ const userProject = userProjects.find((p) => p.id === projectId);
627
+ if (userProject && userProject.role) {
628
+ return userProject.role;
629
+ }
630
+ }
631
+ return await this.getMyProjectRole(projectId);
632
+ }
633
+ /**
634
+ * Get project role with fallback to user projects list (by project key)
635
+ * This method tries to get the role from user projects first,
636
+ * then falls back to API call if not found
637
+ */
638
+ async getProjectRoleByKeyWithFallback(projectKey, userProjects = null) {
639
+ this._requireReady("getProjectRoleByKeyWithFallback");
640
+ if (!projectKey) {
641
+ throw new Error("Project key is required");
642
+ }
643
+ if (userProjects && Array.isArray(userProjects)) {
644
+ const userProject = userProjects.find((p) => p.key === projectKey);
645
+ if (userProject && userProject.role) {
646
+ return userProject.role;
647
+ }
648
+ }
649
+ return await this.getMyProjectRoleByKey(projectKey);
650
+ }
651
+ // ==================== AUTH HELPER METHODS ====================
652
+ /**
653
+ * Debug method to check token status
654
+ */
655
+ getTokenDebugInfo() {
656
+ if (!this._tokenManager) {
657
+ return {
658
+ tokenManagerExists: false,
659
+ error: "TokenManager not initialized"
660
+ };
661
+ }
662
+ const tokenStatus = this._tokenManager.getTokenStatus();
663
+ const { tokens } = this._tokenManager;
664
+ return {
665
+ tokenManagerExists: true,
666
+ tokenStatus,
667
+ hasAccessToken: Boolean(tokens.accessToken),
668
+ hasRefreshToken: Boolean(tokens.refreshToken),
669
+ accessTokenPreview: tokens.accessToken ? `${tokens.accessToken.substring(0, 20)}...` : null,
670
+ expiresAt: tokens.expiresAt,
671
+ timeToExpiry: tokenStatus.timeToExpiry,
672
+ authHeader: this._tokenManager.getAuthHeader()
673
+ };
674
+ }
675
+ /**
676
+ * Helper method to check if user is authenticated
677
+ */
678
+ isAuthenticated() {
679
+ if (!this._tokenManager) {
680
+ return false;
681
+ }
682
+ return this._tokenManager.hasTokens();
683
+ }
684
+ /**
685
+ * Helper method to check if user has valid tokens
686
+ */
687
+ hasValidTokens() {
688
+ if (!this._tokenManager) {
689
+ return false;
204
690
  }
691
+ return this._tokenManager.hasTokens() && this._tokenManager.isAccessTokenValid();
205
692
  }
693
+ /**
694
+ * Helper method to get current user info
695
+ */
696
+ async getCurrentUser() {
697
+ try {
698
+ return await this.getMe();
699
+ } catch (error) {
700
+ throw new Error(`Failed to get current user: ${error.message}`, { cause: error });
701
+ }
702
+ }
703
+ /**
704
+ * Helper method to validate user data for registration
705
+ */
706
+ validateRegistrationData(userData) {
707
+ const errors = [];
708
+ if (!userData.email || typeof userData.email !== "string") {
709
+ errors.push("Email is required and must be a string");
710
+ } else if (!this._isValidEmail(userData.email)) {
711
+ errors.push("Email must be a valid email address");
712
+ }
713
+ if (!userData.password || typeof userData.password !== "string") {
714
+ errors.push("Password is required and must be a string");
715
+ } else if (userData.password.length < 8) {
716
+ errors.push("Password must be at least 8 characters long");
717
+ }
718
+ if (userData.username && typeof userData.username !== "string") {
719
+ errors.push("Username must be a string");
720
+ } else if (userData.username && userData.username.length < 3) {
721
+ errors.push("Username must be at least 3 characters long");
722
+ }
723
+ return {
724
+ isValid: errors.length === 0,
725
+ errors
726
+ };
727
+ }
728
+ /**
729
+ * Helper method to register with validation
730
+ */
731
+ async registerWithValidation(userData, options = {}) {
732
+ const validation = this.validateRegistrationData(userData);
733
+ if (!validation.isValid) {
734
+ throw new Error(`Validation failed: ${validation.errors.join(", ")}`);
735
+ }
736
+ return await this.register(userData, options);
737
+ }
738
+ /**
739
+ * Helper method to login with validation
740
+ */
741
+ async loginWithValidation(email, password, options = {}) {
742
+ if (!email || typeof email !== "string") {
743
+ throw new Error("Email is required and must be a string");
744
+ }
745
+ if (!password || typeof password !== "string") {
746
+ throw new Error("Password is required and must be a string");
747
+ }
748
+ if (!this._isValidEmail(email)) {
749
+ throw new Error("Email must be a valid email address");
750
+ }
751
+ return await this.login(email, password, options);
752
+ }
753
+ /**
754
+ * Private helper to validate email format
755
+ */
756
+ _isValidEmail(email) {
757
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/u;
758
+ return emailRegex.test(email);
759
+ }
760
+ // ==================== PERMISSION METHODS (Existing) ====================
206
761
  hasPermission(requiredPermission) {
207
762
  var _a;
208
763
  const authState = (_a = this._context) == null ? void 0 : _a.state;
@@ -251,23 +806,17 @@ class AuthService extends import_BaseService.BaseService {
251
806
  if (!operationConfig) {
252
807
  return false;
253
808
  }
254
- if (!operationConfig) {
255
- return false;
256
- }
257
809
  const { permissions = [], features = [] } = operationConfig;
258
810
  try {
259
811
  const permissionResults = await Promise.all(
260
812
  permissions.map(
261
- (permission) => this.hasProjectPermission(projectId, permission)
813
+ (permission) => this.checkProjectPermission(projectId, permission)
262
814
  )
263
815
  );
264
816
  const hasPermissions = requireAll ? permissionResults.every(Boolean) : permissionResults.some(Boolean);
265
817
  if (!hasPermissions) {
266
818
  return false;
267
819
  }
268
- if (!hasPermissions) {
269
- return false;
270
- }
271
820
  if (checkFeatures && features.length > 0) {
272
821
  const featureResults = features.map((feature) => {
273
822
  const result = this.hasProjectFeature(projectId, feature);
@@ -277,9 +826,6 @@ class AuthService extends import_BaseService.BaseService {
277
826
  if (!hasFeatures) {
278
827
  return false;
279
828
  }
280
- if (!hasFeatures) {
281
- return false;
282
- }
283
829
  }
284
830
  return true;
285
831
  } catch (error) {
@@ -301,203 +847,90 @@ class AuthService extends import_BaseService.BaseService {
301
847
  }
302
848
  return action();
303
849
  }
304
- // Project access information
305
- async getProjectAccess(projectId) {
306
- this._requireReady();
307
- if (!projectId) {
308
- throw new Error("Project ID is required");
309
- }
310
- const operations = Object.keys(import_permission.PERMISSION_MAP);
311
- const access = await Promise.all(
312
- operations.map(async (operation) => {
313
- const allowed = await this.canPerformOperation(projectId, operation);
314
- const config = import_permission.PERMISSION_MAP[operation];
315
- return {
316
- operation,
317
- allowed,
318
- permissions: config.permissions,
319
- features: config.features,
320
- aiTokens: operation.startsWith("ai") ? this._getAITokens(projectId, operation.replace("ai", "")) : null
321
- };
322
- })
323
- );
324
- return {
325
- projectId,
326
- permissions: access.reduce(
327
- (acc, { operation, ...details }) => ({
328
- ...acc,
329
- [operation]: details
330
- }),
331
- {}
332
- ),
333
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
334
- };
335
- }
336
- // AI token management
337
- _getAITokens(projectId, featureType) {
338
- const tokenFeatures = [
339
- `ai${featureType}:3`,
340
- `ai${featureType}:5`,
341
- `ai${featureType}:15`
342
- ];
343
- return tokenFeatures.reduce((total, feature) => {
344
- const tokens = this.hasProjectFeature(projectId, feature);
345
- return total + (typeof tokens === "number" ? tokens : 0);
346
- }, 0);
347
- }
348
- async getProjectMembers(projectId) {
349
- var _a;
350
- this._requireReady("getProjectMembers");
351
- if (!projectId) {
352
- throw new Error("Project ID is required");
353
- }
354
- try {
355
- const based = this._getBasedService("getProjectMembers");
356
- return await based.call("projects:get-members", { projectId });
357
- } catch (error) {
358
- if ((_a = error.message) == null ? void 0 : _a.includes("Authentication failed. Please try again"))
359
- window.location.reload();
360
- throw new Error(`Failed to get project members: ${error.message}`);
850
+ // Cleanup
851
+ destroy() {
852
+ if (this._tokenManager) {
853
+ this._tokenManager.destroy();
854
+ this._tokenManager = null;
361
855
  }
856
+ this._projectRoleCache.clear();
857
+ this._setReady(false);
362
858
  }
363
- async inviteMember(projectId, email, role, name, callbackUrl) {
364
- this._requireReady("inviteMember");
365
- if (!projectId) {
366
- throw new Error("Project ID is required");
367
- }
368
- if (!email) {
369
- throw new Error("Email is required");
370
- }
371
- if (!callbackUrl || Object.keys(callbackUrl).length === 0) {
372
- throw new Error("Callback Url is required");
373
- }
374
- if (!role || !this._userRoles.has(role)) {
375
- throw new Error(`Invalid role: ${role}`);
376
- }
377
- try {
378
- const based = this._getBasedService("inviteMember");
379
- return await based.call("projects:invite-member", {
380
- projectId,
381
- email,
382
- role,
383
- name,
384
- callbackUrl
385
- });
386
- } catch (error) {
387
- throw new Error(`Failed to invite member: ${error.message}`);
859
+ _preparePluginPayload(payload, sessionOverride = null) {
860
+ const target = payload && typeof payload === "object" ? { ...payload } : {};
861
+ const session = this._resolvePluginSession(sessionOverride);
862
+ if (session && !Object.hasOwn(target, "session")) {
863
+ target.session = session;
864
+ return { payload: target, session };
388
865
  }
866
+ return { payload: target, session: null };
389
867
  }
390
- async acceptInvite(token) {
391
- this._requireReady("acceptInvite");
392
- try {
393
- const based = this._getBasedService("acceptInvite");
394
- return await based.call("projects:accept-invite", { token });
395
- } catch (error) {
396
- throw new Error(`Failed to accept invite: ${error.message}`);
868
+ _resolvePluginSession(sessionOverride = null) {
869
+ var _a, _b;
870
+ if (sessionOverride) {
871
+ return this._cachePluginSession(sessionOverride);
397
872
  }
398
- }
399
- async updateMemberRole(projectId, userId, role) {
400
- this._requireReady("updateMemberRole");
401
- if (!projectId) {
402
- throw new Error("Project ID is required");
873
+ if (this._pluginSession) {
874
+ return this._pluginSession;
403
875
  }
404
- if (!userId) {
405
- throw new Error("User ID is required");
876
+ const optionSession = (_a = this._options) == null ? void 0 : _a.pluginSession;
877
+ if (optionSession) {
878
+ return this._cachePluginSession(optionSession);
406
879
  }
407
- if (!this._userRoles.has(role)) {
408
- throw new Error(`Invalid role: ${role}`);
880
+ const contextSession = (_b = this._context) == null ? void 0 : _b.pluginSession;
881
+ if (contextSession) {
882
+ return this._cachePluginSession(contextSession);
409
883
  }
410
- try {
411
- const based = this._getBasedService("updateMemberRole");
412
- return await based.call("projects:update-member-role", {
413
- projectId,
414
- userId,
415
- role
416
- });
417
- } catch (error) {
418
- throw new Error(`Failed to update member role: ${error.message}`);
884
+ if (typeof window !== "undefined") {
885
+ try {
886
+ const sessionFromUrl = new URL(window.location.href).searchParams.get("session");
887
+ if (sessionFromUrl) {
888
+ return this._cachePluginSession(sessionFromUrl);
889
+ }
890
+ } catch {
891
+ }
892
+ try {
893
+ if (window.localStorage) {
894
+ const stored = window.localStorage.getItem(PLUGIN_SESSION_STORAGE_KEY);
895
+ if (stored) {
896
+ this._pluginSession = stored;
897
+ return stored;
898
+ }
899
+ }
900
+ } catch {
901
+ }
419
902
  }
903
+ return null;
420
904
  }
421
- async removeMember(projectId, userId) {
422
- this._requireReady("removeMember");
423
- if (!projectId || !userId) {
424
- throw new Error("Project ID and user ID are required");
905
+ _cachePluginSession(session) {
906
+ if (!session) {
907
+ return null;
425
908
  }
426
- try {
427
- const based = this._getBasedService("removeMember");
428
- return await based.call("projects:remove-member", { projectId, userId });
429
- } catch (error) {
430
- throw new Error(`Failed to remove member: ${error.message}`);
909
+ this._pluginSession = session;
910
+ if (typeof window !== "undefined") {
911
+ try {
912
+ if (window.localStorage) {
913
+ window.localStorage.setItem(PLUGIN_SESSION_STORAGE_KEY, session);
914
+ }
915
+ } catch {
916
+ }
431
917
  }
918
+ return session;
432
919
  }
433
- async confirmRegistration(token) {
434
- try {
435
- const based = this._getBasedService("confirmRegistration");
436
- return await based.call("users:register-confirmation", { token });
437
- } catch (error) {
438
- throw new Error(`Registration confirmation failed: ${error.message}`);
439
- }
920
+ setPluginSession(session) {
921
+ this._cachePluginSession(session);
440
922
  }
441
- async requestPasswordReset(email, callbackUrl) {
442
- try {
443
- const based = this._getBasedService("requestPasswordReset");
444
- return await based.call("users:reset-password", { email, callbackUrl });
445
- } catch (error) {
446
- throw new Error(`Password reset request failed: ${error.message}`);
923
+ _clearPluginSession(session = null) {
924
+ if (!session || this._pluginSession === session) {
925
+ this._pluginSession = null;
447
926
  }
448
- }
449
- async confirmPasswordReset(token, newPassword) {
450
- try {
451
- const based = this._getBasedService("confirmPasswordReset");
452
- return await based.call("users:reset-password-confirm", {
453
- token,
454
- newPassword
455
- });
456
- } catch (error) {
457
- throw new Error(`Password reset confirmation failed: ${error.message}`);
458
- }
459
- }
460
- async getStoredAuthState() {
461
- try {
462
- const based = this._getBasedService("getStoredAuthState");
463
- const { authState } = based;
464
- if (authState == null ? void 0 : authState.token) {
465
- return {
466
- userId: authState.userId,
467
- authToken: authState.token,
468
- projectRoles: authState.projectRoles,
469
- globalRole: authState.globalRole,
470
- error: null
471
- };
927
+ if (typeof window !== "undefined") {
928
+ try {
929
+ if (window.localStorage) {
930
+ window.localStorage.removeItem(PLUGIN_SESSION_STORAGE_KEY);
931
+ }
932
+ } catch {
472
933
  }
473
- return {
474
- userId: false,
475
- authToken: false
476
- };
477
- } catch (error) {
478
- this._setError(error);
479
- return {
480
- userId: false,
481
- authToken: false,
482
- error: `Failed to get stored auth state: ${error.message}`
483
- };
484
934
  }
485
935
  }
486
- async subscribeToAuthChanges(callback) {
487
- const based = this._getBasedService("subscribeToAuthChanges");
488
- based.on("authstate-change", async (authState) => {
489
- const formattedState = (authState == null ? void 0 : authState.token) ? {
490
- userId: authState.userId,
491
- authToken: authState.token,
492
- projectRoles: authState.projectRoles,
493
- globalRole: authState.globalRole,
494
- error: null
495
- } : {
496
- userId: false,
497
- authToken: false
498
- };
499
- await callback(formattedState);
500
- });
501
- return () => based.off("authstate-change");
502
- }
503
936
  }