@symbo.ls/sdk 2.34.35 → 3.1.2
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.
- package/README.md +2 -143
- package/dist/cjs/config/environment.js +30 -98
- package/dist/cjs/index.js +24 -144
- package/dist/cjs/services/AIService.js +155 -0
- package/dist/cjs/services/AuthService.js +305 -738
- package/dist/cjs/services/BaseService.js +6 -158
- package/dist/cjs/services/BasedService.js +1185 -0
- package/dist/cjs/services/CoreService.js +1751 -0
- package/dist/cjs/services/SocketIOService.js +307 -0
- package/dist/cjs/services/SocketService.js +161 -0
- package/dist/cjs/services/SymstoryService.js +571 -0
- package/dist/cjs/services/index.js +16 -64
- package/dist/cjs/utils/TokenManager.js +30 -78
- package/dist/cjs/utils/basedQuerys.js +181 -0
- package/dist/cjs/utils/services.js +103 -301
- package/dist/cjs/utils/symstoryClient.js +259 -0
- package/dist/cjs/utils/validation.js +3 -0
- package/dist/esm/config/environment.js +30 -98
- package/dist/esm/index.js +8797 -49416
- package/dist/esm/services/AIService.js +185 -0
- package/dist/esm/services/AuthService.js +386 -1493
- package/dist/esm/services/BaseService.js +6 -757
- package/dist/esm/services/BasedService.js +5278 -0
- package/dist/esm/services/CoreService.js +2264 -0
- package/dist/esm/services/SocketIOService.js +470 -0
- package/dist/esm/services/SocketService.js +191 -0
- package/dist/esm/services/SymstoryService.js +7041 -0
- package/dist/esm/services/index.js +8690 -49015
- package/dist/esm/utils/TokenManager.js +30 -78
- package/dist/esm/utils/basedQuerys.js +163 -0
- package/dist/esm/utils/services.js +103 -301
- package/dist/esm/utils/symstoryClient.js +370 -0
- package/dist/esm/utils/validation.js +7 -4
- package/dist/node/config/environment.js +30 -98
- package/dist/node/index.js +32 -175
- package/dist/node/services/AIService.js +136 -0
- package/dist/node/services/AuthService.js +310 -742
- package/dist/node/services/BaseService.js +6 -148
- package/dist/node/services/BasedService.js +1156 -0
- package/dist/node/services/CoreService.js +1722 -0
- package/dist/node/services/SocketIOService.js +278 -0
- package/dist/node/services/SocketService.js +142 -0
- package/dist/node/services/SymstoryService.js +542 -0
- package/dist/node/services/index.js +16 -64
- package/dist/node/utils/TokenManager.js +30 -78
- package/dist/node/utils/basedQuerys.js +162 -0
- package/dist/node/utils/services.js +103 -301
- package/dist/node/utils/symstoryClient.js +230 -0
- package/dist/node/utils/validation.js +3 -0
- package/package.json +16 -35
- package/src/config/environment.js +28 -99
- package/src/index.js +36 -181
- package/src/services/AIService.js +150 -0
- package/src/services/AuthService.js +328 -874
- package/src/services/BaseService.js +6 -166
- package/src/services/BasedService.js +1301 -0
- package/src/services/CoreService.js +1943 -0
- package/src/services/SocketIOService.js +334 -0
- package/src/services/SocketService.js +168 -0
- package/src/services/SymstoryService.js +649 -0
- package/src/services/index.js +13 -80
- package/src/utils/TokenManager.js +33 -88
- package/src/utils/basedQuerys.js +164 -0
- package/src/utils/services.js +107 -326
- package/src/utils/symstoryClient.js +252 -0
- package/src/utils/validation.js +3 -0
- package/dist/cjs/services/AdminService.js +0 -351
- package/dist/cjs/services/BranchService.js +0 -484
- package/dist/cjs/services/CollabService.js +0 -743
- package/dist/cjs/services/DnsService.js +0 -340
- package/dist/cjs/services/FeatureFlagService.js +0 -175
- package/dist/cjs/services/FileService.js +0 -201
- package/dist/cjs/services/IntegrationService.js +0 -538
- package/dist/cjs/services/MetricsService.js +0 -62
- package/dist/cjs/services/PaymentService.js +0 -271
- package/dist/cjs/services/PlanService.js +0 -426
- package/dist/cjs/services/ProjectService.js +0 -1207
- package/dist/cjs/services/PullRequestService.js +0 -503
- package/dist/cjs/services/ScreenshotService.js +0 -304
- package/dist/cjs/services/SubscriptionService.js +0 -396
- package/dist/cjs/services/TrackingService.js +0 -661
- package/dist/cjs/services/WaitlistService.js +0 -148
- package/dist/cjs/state/RootStateManager.js +0 -65
- package/dist/cjs/state/rootEventBus.js +0 -74
- package/dist/cjs/utils/CollabClient.js +0 -223
- package/dist/cjs/utils/changePreprocessor.js +0 -199
- package/dist/cjs/utils/jsonDiff.js +0 -145
- package/dist/cjs/utils/ordering.js +0 -309
- package/dist/esm/services/AdminService.js +0 -1132
- package/dist/esm/services/BranchService.js +0 -1265
- package/dist/esm/services/CollabService.js +0 -26838
- package/dist/esm/services/DnsService.js +0 -1121
- package/dist/esm/services/FeatureFlagService.js +0 -956
- package/dist/esm/services/FileService.js +0 -982
- package/dist/esm/services/IntegrationService.js +0 -1319
- package/dist/esm/services/MetricsService.js +0 -843
- package/dist/esm/services/PaymentService.js +0 -1052
- package/dist/esm/services/PlanService.js +0 -1207
- package/dist/esm/services/ProjectService.js +0 -2526
- package/dist/esm/services/PullRequestService.js +0 -1284
- package/dist/esm/services/ScreenshotService.js +0 -1085
- package/dist/esm/services/SubscriptionService.js +0 -1177
- package/dist/esm/services/TrackingService.js +0 -18343
- package/dist/esm/services/WaitlistService.js +0 -929
- package/dist/esm/state/RootStateManager.js +0 -90
- package/dist/esm/state/rootEventBus.js +0 -56
- package/dist/esm/utils/CollabClient.js +0 -18901
- package/dist/esm/utils/changePreprocessor.js +0 -542
- package/dist/esm/utils/jsonDiff.js +0 -7011
- package/dist/esm/utils/ordering.js +0 -291
- package/dist/node/services/AdminService.js +0 -332
- package/dist/node/services/BranchService.js +0 -465
- package/dist/node/services/CollabService.js +0 -724
- package/dist/node/services/DnsService.js +0 -321
- package/dist/node/services/FeatureFlagService.js +0 -156
- package/dist/node/services/FileService.js +0 -182
- package/dist/node/services/IntegrationService.js +0 -519
- package/dist/node/services/MetricsService.js +0 -43
- package/dist/node/services/PaymentService.js +0 -252
- package/dist/node/services/PlanService.js +0 -407
- package/dist/node/services/ProjectService.js +0 -1188
- package/dist/node/services/PullRequestService.js +0 -484
- package/dist/node/services/ScreenshotService.js +0 -285
- package/dist/node/services/SubscriptionService.js +0 -377
- package/dist/node/services/TrackingService.js +0 -632
- package/dist/node/services/WaitlistService.js +0 -129
- package/dist/node/state/RootStateManager.js +0 -36
- package/dist/node/state/rootEventBus.js +0 -55
- package/dist/node/utils/CollabClient.js +0 -194
- package/dist/node/utils/changePreprocessor.js +0 -180
- package/dist/node/utils/jsonDiff.js +0 -116
- package/dist/node/utils/ordering.js +0 -290
- package/src/services/AdminService.js +0 -374
- package/src/services/BranchService.js +0 -536
- package/src/services/CollabService.js +0 -900
- package/src/services/DnsService.js +0 -366
- package/src/services/FeatureFlagService.js +0 -174
- package/src/services/FileService.js +0 -213
- package/src/services/IntegrationService.js +0 -548
- package/src/services/MetricsService.js +0 -40
- package/src/services/PaymentService.js +0 -287
- package/src/services/PlanService.js +0 -468
- package/src/services/ProjectService.js +0 -1366
- package/src/services/PullRequestService.js +0 -537
- package/src/services/ScreenshotService.js +0 -258
- package/src/services/SubscriptionService.js +0 -425
- package/src/services/TrackingService.js +0 -853
- package/src/services/WaitlistService.js +0 -130
- package/src/services/tests/BranchService/createBranch.test.js +0 -153
- package/src/services/tests/BranchService/deleteBranch.test.js +0 -173
- package/src/services/tests/BranchService/getBranchChanges.test.js +0 -146
- package/src/services/tests/BranchService/listBranches.test.js +0 -87
- package/src/services/tests/BranchService/mergeBranch.test.js +0 -210
- package/src/services/tests/BranchService/publishVersion.test.js +0 -183
- package/src/services/tests/BranchService/renameBranch.test.js +0 -240
- package/src/services/tests/BranchService/resetBranch.test.js +0 -152
- package/src/services/tests/FeatureFlagService/adminFeatureFlags.test.js +0 -67
- package/src/services/tests/FeatureFlagService/getFeatureFlags.test.js +0 -75
- package/src/services/tests/FileService/createFileFormData.test.js +0 -74
- package/src/services/tests/FileService/getFileUrl.test.js +0 -69
- package/src/services/tests/FileService/updateProjectIcon.test.js +0 -109
- package/src/services/tests/FileService/uploadDocument.test.js +0 -36
- package/src/services/tests/FileService/uploadFile.test.js +0 -78
- package/src/services/tests/FileService/uploadFileWithValidation.test.js +0 -114
- package/src/services/tests/FileService/uploadImage.test.js +0 -36
- package/src/services/tests/FileService/uploadMultipleFiles.test.js +0 -111
- package/src/services/tests/FileService/validateFile.test.js +0 -63
- package/src/services/tests/PlanService/createPlan.test.js +0 -104
- package/src/services/tests/PlanService/createPlanWithValidation.test.js +0 -523
- package/src/services/tests/PlanService/deletePlan.test.js +0 -92
- package/src/services/tests/PlanService/getActivePlans.test.js +0 -123
- package/src/services/tests/PlanService/getAdminPlans.test.js +0 -84
- package/src/services/tests/PlanService/getPlan.test.js +0 -50
- package/src/services/tests/PlanService/getPlanByKey.test.js +0 -109
- package/src/services/tests/PlanService/getPlanWithValidation.test.js +0 -85
- package/src/services/tests/PlanService/getPlans.test.js +0 -53
- package/src/services/tests/PlanService/getPlansByPriceRange.test.js +0 -109
- package/src/services/tests/PlanService/getPlansWithValidation.test.js +0 -48
- package/src/services/tests/PlanService/initializePlans.test.js +0 -75
- package/src/services/tests/PlanService/updatePlan.test.js +0 -111
- package/src/services/tests/PlanService/updatePlanWithValidation.test.js +0 -556
- package/src/state/RootStateManager.js +0 -76
- package/src/state/rootEventBus.js +0 -67
- package/src/utils/CollabClient.js +0 -248
- package/src/utils/changePreprocessor.js +0 -239
- package/src/utils/jsonDiff.js +0 -144
- package/src/utils/ordering.js +0 -271
|
@@ -22,742 +22,187 @@ __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";
|
|
26
25
|
class AuthService extends import_BaseService.BaseService {
|
|
27
26
|
constructor(config) {
|
|
28
|
-
var _a, _b;
|
|
29
27
|
super(config);
|
|
30
28
|
this._userRoles = /* @__PURE__ */ new Set(["guest", "editor", "admin", "owner"]);
|
|
31
29
|
this._projectTiers = /* @__PURE__ */ new Set([
|
|
32
30
|
"ready",
|
|
33
|
-
"
|
|
31
|
+
"free",
|
|
34
32
|
"pro1",
|
|
35
33
|
"pro2",
|
|
36
34
|
"enterprise"
|
|
37
35
|
]);
|
|
38
|
-
this.
|
|
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
|
-
);
|
|
44
|
-
}
|
|
45
|
-
// Use BaseService.init/_request/_requireReady implementations
|
|
46
|
-
// ==================== AUTH METHODS ====================
|
|
47
|
-
async register(userData, options = {}) {
|
|
48
|
-
try {
|
|
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);
|
|
61
|
-
}
|
|
62
|
-
return response.data;
|
|
63
|
-
}
|
|
64
|
-
throw new Error(response.message);
|
|
65
|
-
} catch (error) {
|
|
66
|
-
throw new Error(`Registration failed: ${error.message}`, { cause: error });
|
|
67
|
-
}
|
|
36
|
+
this._initialized = false;
|
|
68
37
|
}
|
|
69
|
-
|
|
70
|
-
|
|
38
|
+
// eslint-disable-next-line no-empty-pattern
|
|
39
|
+
init({}) {
|
|
71
40
|
try {
|
|
72
|
-
const {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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);
|
|
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)
|
|
94
47
|
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
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 });
|
|
105
|
-
}
|
|
106
|
-
}
|
|
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 = {}) {
|
|
140
|
-
var _a;
|
|
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);
|
|
48
|
+
};
|
|
49
|
+
this._initialized = true;
|
|
50
|
+
this._setReady();
|
|
170
51
|
} catch (error) {
|
|
171
|
-
|
|
172
|
-
|
|
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);
|
|
173
68
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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"
|
|
185
|
-
});
|
|
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);
|
|
205
|
-
} catch (error) {
|
|
206
|
-
throw new Error(`GitHub auth failed: ${error.message}`, { cause: error });
|
|
69
|
+
_requireReady(methodName) {
|
|
70
|
+
if (this._requiresInit(methodName) && !this._initialized) {
|
|
71
|
+
throw new Error("Service not initialized");
|
|
207
72
|
}
|
|
208
73
|
}
|
|
209
|
-
|
|
74
|
+
_getBasedService(methodName) {
|
|
210
75
|
var _a;
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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);
|
|
243
|
-
} catch (error) {
|
|
244
|
-
throw new Error(`Google auth callback failed: ${error.message}`, { cause: error });
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
async requestPasswordReset(email) {
|
|
248
|
-
try {
|
|
249
|
-
const response = await this._request("/auth/request-password-reset", {
|
|
250
|
-
method: "POST",
|
|
251
|
-
body: JSON.stringify({ email }),
|
|
252
|
-
methodName: "requestPasswordReset"
|
|
253
|
-
});
|
|
254
|
-
if (response.success) {
|
|
255
|
-
return response.data;
|
|
256
|
-
}
|
|
257
|
-
throw new Error(response.message);
|
|
258
|
-
} catch (error) {
|
|
259
|
-
throw new Error(`Password reset request failed: ${error.message}`, { cause: error });
|
|
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");
|
|
260
79
|
}
|
|
80
|
+
return based._client;
|
|
261
81
|
}
|
|
262
|
-
async
|
|
82
|
+
async login(identifier, password) {
|
|
263
83
|
try {
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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
|
|
268
95
|
});
|
|
269
|
-
|
|
270
|
-
return response.data;
|
|
271
|
-
}
|
|
272
|
-
throw new Error(response.message);
|
|
96
|
+
return response;
|
|
273
97
|
} catch (error) {
|
|
274
|
-
throw new Error(`
|
|
98
|
+
throw new Error(`Login failed: ${error.message}`);
|
|
275
99
|
}
|
|
276
100
|
}
|
|
277
|
-
async
|
|
101
|
+
async register(userData) {
|
|
278
102
|
try {
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
body: JSON.stringify({ token }),
|
|
282
|
-
methodName: "confirmRegistration"
|
|
283
|
-
});
|
|
284
|
-
if (response.success) {
|
|
285
|
-
return response.data;
|
|
286
|
-
}
|
|
287
|
-
throw new Error(response.message);
|
|
103
|
+
const based = this._getBasedService("register");
|
|
104
|
+
return await based.call("users:register", userData);
|
|
288
105
|
} catch (error) {
|
|
289
|
-
throw new Error(`Registration
|
|
106
|
+
throw new Error(`Registration failed: ${error.message}`);
|
|
290
107
|
}
|
|
291
108
|
}
|
|
292
|
-
async
|
|
293
|
-
this._requireReady("requestPasswordChange");
|
|
109
|
+
async googleAuth(idToken) {
|
|
294
110
|
try {
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
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
|
|
298
120
|
});
|
|
299
|
-
|
|
300
|
-
return response.data;
|
|
301
|
-
}
|
|
302
|
-
throw new Error(response.message);
|
|
121
|
+
return response;
|
|
303
122
|
} catch (error) {
|
|
304
|
-
throw new Error(`
|
|
123
|
+
throw new Error(`Google auth failed: ${error.message}`);
|
|
305
124
|
}
|
|
306
125
|
}
|
|
307
|
-
async
|
|
308
|
-
this._requireReady("confirmPasswordChange");
|
|
126
|
+
async googleAuthCallback(code, redirectUri) {
|
|
309
127
|
try {
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
128
|
+
const based = this._getBasedService("googleAuthCallback");
|
|
129
|
+
const response = await based.call("users:google-auth-callback", {
|
|
130
|
+
code,
|
|
131
|
+
redirectUri
|
|
314
132
|
});
|
|
315
|
-
if (
|
|
316
|
-
|
|
133
|
+
if (this._initialized) {
|
|
134
|
+
this.updateContext({ authToken: response.token });
|
|
317
135
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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"
|
|
136
|
+
based.setAuthState({
|
|
137
|
+
token: response.token,
|
|
138
|
+
userId: response.userId,
|
|
139
|
+
persistent: true
|
|
331
140
|
});
|
|
332
|
-
|
|
333
|
-
return response.data;
|
|
334
|
-
}
|
|
335
|
-
throw new Error(response.message);
|
|
141
|
+
return response;
|
|
336
142
|
} catch (error) {
|
|
337
|
-
throw new Error(`
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
getAuthToken() {
|
|
341
|
-
if (!this._tokenManager) {
|
|
342
|
-
return null;
|
|
143
|
+
throw new Error(`Google auth callback failed: ${error.message}`);
|
|
343
144
|
}
|
|
344
|
-
return this._tokenManager.getAccessToken();
|
|
345
145
|
}
|
|
346
|
-
|
|
347
|
-
* Get stored authentication state (backward compatibility method)
|
|
348
|
-
* Replaces AuthService.getStoredAuthState()
|
|
349
|
-
*/
|
|
350
|
-
async getStoredAuthState() {
|
|
146
|
+
async githubAuth(code) {
|
|
351
147
|
try {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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"
|
|
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
|
|
453
157
|
});
|
|
454
|
-
|
|
455
|
-
return response.data;
|
|
456
|
-
}
|
|
457
|
-
throw new Error(response.message);
|
|
158
|
+
return response;
|
|
458
159
|
} catch (error) {
|
|
459
|
-
throw new Error(`
|
|
160
|
+
throw new Error(`GitHub auth failed: ${error.message}`);
|
|
460
161
|
}
|
|
461
162
|
}
|
|
462
|
-
async
|
|
463
|
-
this._requireReady("
|
|
163
|
+
async logout() {
|
|
164
|
+
this._requireReady("logout");
|
|
464
165
|
try {
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
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);
|
|
166
|
+
const based = this._getBasedService("logout");
|
|
167
|
+
await based.call("users:logout");
|
|
168
|
+
this.updateContext({ authToken: null });
|
|
481
169
|
} catch (error) {
|
|
482
|
-
throw new Error(`
|
|
170
|
+
throw new Error(`Logout failed: ${error.message}`);
|
|
483
171
|
}
|
|
484
172
|
}
|
|
485
|
-
async
|
|
486
|
-
this._requireReady("
|
|
173
|
+
async updateUserRole(userId, newRole) {
|
|
174
|
+
this._requireReady("updateUserRole");
|
|
487
175
|
if (!userId) {
|
|
488
176
|
throw new Error("User ID is required");
|
|
489
177
|
}
|
|
490
|
-
|
|
491
|
-
|
|
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");
|
|
178
|
+
if (!this._userRoles.has(newRole)) {
|
|
179
|
+
throw new Error(`Invalid role: ${newRole}`);
|
|
507
180
|
}
|
|
508
181
|
try {
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
methodName: "getUserByEmail"
|
|
512
|
-
});
|
|
513
|
-
if (response.success) {
|
|
514
|
-
return response.data.user;
|
|
515
|
-
}
|
|
516
|
-
throw new Error(response.message);
|
|
182
|
+
const based = this._getBasedService("updateUserRole");
|
|
183
|
+
return await based.call("users:update-role", { userId, role: newRole });
|
|
517
184
|
} catch (error) {
|
|
518
|
-
throw new Error(`Failed to
|
|
185
|
+
throw new Error(`Failed to update user role: ${error.message}`);
|
|
519
186
|
}
|
|
520
187
|
}
|
|
521
|
-
|
|
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");
|
|
188
|
+
async updateProjectTier(projectId, newTier) {
|
|
189
|
+
this._requireReady("updateProjectTier");
|
|
528
190
|
if (!projectId) {
|
|
529
191
|
throw new Error("Project ID is required");
|
|
530
192
|
}
|
|
531
|
-
if (!this.
|
|
532
|
-
|
|
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;
|
|
193
|
+
if (!this._projectTiers.has(newTier)) {
|
|
194
|
+
throw new Error(`Invalid project tier: ${newTier}`);
|
|
577
195
|
}
|
|
578
196
|
try {
|
|
579
|
-
const
|
|
580
|
-
|
|
581
|
-
|
|
197
|
+
const based = this._getBasedService("updateProjectTier");
|
|
198
|
+
return await based.call("projects:update-tier", {
|
|
199
|
+
projectId,
|
|
200
|
+
tier: newTier
|
|
582
201
|
});
|
|
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);
|
|
592
202
|
} catch (error) {
|
|
593
|
-
|
|
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;
|
|
203
|
+
throw new Error(`Failed to update project tier: ${error.message}`);
|
|
690
204
|
}
|
|
691
|
-
return this._tokenManager.hasTokens() && this._tokenManager.isAccessTokenValid();
|
|
692
205
|
}
|
|
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) ====================
|
|
761
206
|
hasPermission(requiredPermission) {
|
|
762
207
|
var _a;
|
|
763
208
|
const authState = (_a = this._context) == null ? void 0 : _a.state;
|
|
@@ -806,17 +251,23 @@ class AuthService extends import_BaseService.BaseService {
|
|
|
806
251
|
if (!operationConfig) {
|
|
807
252
|
return false;
|
|
808
253
|
}
|
|
254
|
+
if (!operationConfig) {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
809
257
|
const { permissions = [], features = [] } = operationConfig;
|
|
810
258
|
try {
|
|
811
259
|
const permissionResults = await Promise.all(
|
|
812
260
|
permissions.map(
|
|
813
|
-
(permission) => this.
|
|
261
|
+
(permission) => this.hasProjectPermission(projectId, permission)
|
|
814
262
|
)
|
|
815
263
|
);
|
|
816
264
|
const hasPermissions = requireAll ? permissionResults.every(Boolean) : permissionResults.some(Boolean);
|
|
817
265
|
if (!hasPermissions) {
|
|
818
266
|
return false;
|
|
819
267
|
}
|
|
268
|
+
if (!hasPermissions) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
820
271
|
if (checkFeatures && features.length > 0) {
|
|
821
272
|
const featureResults = features.map((feature) => {
|
|
822
273
|
const result = this.hasProjectFeature(projectId, feature);
|
|
@@ -826,6 +277,9 @@ class AuthService extends import_BaseService.BaseService {
|
|
|
826
277
|
if (!hasFeatures) {
|
|
827
278
|
return false;
|
|
828
279
|
}
|
|
280
|
+
if (!hasFeatures) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
829
283
|
}
|
|
830
284
|
return true;
|
|
831
285
|
} catch (error) {
|
|
@@ -847,90 +301,203 @@ class AuthService extends import_BaseService.BaseService {
|
|
|
847
301
|
}
|
|
848
302
|
return action();
|
|
849
303
|
}
|
|
850
|
-
//
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
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}`);
|
|
855
361
|
}
|
|
856
|
-
this._projectRoleCache.clear();
|
|
857
|
-
this._setReady(false);
|
|
858
362
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
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}`);
|
|
865
388
|
}
|
|
866
|
-
return { payload: target, session: null };
|
|
867
389
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
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}`);
|
|
872
397
|
}
|
|
873
|
-
|
|
874
|
-
|
|
398
|
+
}
|
|
399
|
+
async updateMemberRole(projectId, userId, role) {
|
|
400
|
+
this._requireReady("updateMemberRole");
|
|
401
|
+
if (!projectId) {
|
|
402
|
+
throw new Error("Project ID is required");
|
|
875
403
|
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
return this._cachePluginSession(optionSession);
|
|
404
|
+
if (!userId) {
|
|
405
|
+
throw new Error("User ID is required");
|
|
879
406
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
return this._cachePluginSession(contextSession);
|
|
407
|
+
if (!this._userRoles.has(role)) {
|
|
408
|
+
throw new Error(`Invalid role: ${role}`);
|
|
883
409
|
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
|
|
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
|
-
}
|
|
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}`);
|
|
902
419
|
}
|
|
903
|
-
return null;
|
|
904
420
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
421
|
+
async removeMember(projectId, userId) {
|
|
422
|
+
this._requireReady("removeMember");
|
|
423
|
+
if (!projectId || !userId) {
|
|
424
|
+
throw new Error("Project ID and user ID are required");
|
|
908
425
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
}
|
|
915
|
-
} catch {
|
|
916
|
-
}
|
|
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}`);
|
|
917
431
|
}
|
|
918
|
-
return session;
|
|
919
432
|
}
|
|
920
|
-
|
|
921
|
-
|
|
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
|
+
}
|
|
922
440
|
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
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}`);
|
|
926
447
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
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
|
+
};
|
|
933
472
|
}
|
|
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
|
+
};
|
|
934
484
|
}
|
|
935
485
|
}
|
|
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
|
+
}
|
|
936
503
|
}
|