@symbo.ls/sdk 2.34.35 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -315
- package/dist/cjs/config/environment.js +50 -124
- package/dist/cjs/index.js +22 -169
- package/dist/cjs/services/AIService.js +155 -0
- package/dist/cjs/services/AuthService.js +277 -751
- package/dist/cjs/services/BaseService.js +6 -158
- package/dist/cjs/services/BasedService.js +679 -0
- package/dist/cjs/services/SocketIOService.js +309 -0
- package/dist/cjs/services/SocketService.js +161 -0
- package/dist/cjs/services/SymstoryService.js +485 -0
- package/dist/cjs/services/index.js +16 -64
- package/dist/cjs/utils/basedQuerys.js +61 -0
- package/dist/cjs/utils/permission.js +4 -4
- package/dist/cjs/utils/services.js +80 -301
- package/dist/cjs/utils/symstoryClient.js +228 -0
- package/dist/cjs/utils/validation.js +3 -0
- package/dist/esm/config/environment.js +50 -124
- package/dist/esm/index.js +11282 -49789
- package/dist/esm/services/AIService.js +185 -0
- package/dist/esm/services/AuthService.js +358 -1506
- package/dist/esm/services/BaseService.js +6 -757
- package/dist/esm/services/BasedService.js +4651 -0
- package/dist/esm/services/SocketIOService.js +467 -0
- package/dist/esm/services/SocketService.js +191 -0
- package/dist/esm/services/SymstoryService.js +6849 -0
- package/dist/esm/services/index.js +11188 -49352
- package/dist/esm/utils/basedQuerys.js +43 -0
- package/dist/esm/utils/permission.js +4 -4
- package/dist/esm/utils/services.js +80 -301
- package/dist/esm/utils/symstoryClient.js +334 -0
- package/dist/esm/utils/validation.js +26 -93
- package/dist/node/config/environment.js +50 -124
- package/dist/node/index.js +26 -202
- package/dist/node/services/AIService.js +136 -0
- package/dist/node/services/AuthService.js +278 -751
- package/dist/node/services/BaseService.js +6 -148
- package/dist/node/services/BasedService.js +650 -0
- package/dist/node/services/SocketIOService.js +280 -0
- package/dist/node/services/SocketService.js +142 -0
- package/dist/node/services/SymstoryService.js +456 -0
- package/dist/node/services/index.js +16 -64
- package/dist/node/utils/basedQuerys.js +42 -0
- package/dist/node/utils/permission.js +4 -4
- package/dist/node/utils/services.js +80 -301
- package/dist/node/utils/symstoryClient.js +199 -0
- package/dist/node/utils/validation.js +3 -0
- package/package.json +21 -43
- package/src/config/environment.js +50 -126
- package/src/index.js +24 -208
- package/src/services/AIService.js +150 -0
- package/src/services/AuthService.js +298 -893
- package/src/services/BaseService.js +6 -166
- package/src/services/BasedService.js +722 -0
- package/src/services/SocketIOService.js +356 -0
- package/src/services/SocketService.js +168 -0
- package/src/services/SymstoryService.js +563 -0
- package/src/services/index.js +13 -80
- package/src/utils/basedQuerys.js +41 -0
- package/src/utils/permission.js +4 -4
- package/src/utils/services.js +83 -325
- package/src/utils/symstoryClient.js +218 -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/TokenManager.js +0 -422
- 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/TokenManager.js +0 -408
- 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/TokenManager.js +0 -403
- 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/TokenManager.js +0 -479
- package/src/utils/changePreprocessor.js +0 -239
- package/src/utils/jsonDiff.js +0 -144
- package/src/utils/ordering.js +0 -271
|
@@ -22,742 +22,149 @@ __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);
|
|
48
|
+
};
|
|
49
|
+
this._initialized = true;
|
|
50
|
+
this._setReady();
|
|
135
51
|
} catch (error) {
|
|
136
|
-
|
|
137
|
-
|
|
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);
|
|
138
68
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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 });
|
|
69
|
+
_requireReady(methodName) {
|
|
70
|
+
if (this._requiresInit(methodName) && !this._initialized) {
|
|
71
|
+
throw new Error("Service not initialized");
|
|
172
72
|
}
|
|
173
73
|
}
|
|
174
|
-
|
|
74
|
+
_getBasedService(methodName) {
|
|
175
75
|
var _a;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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 });
|
|
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");
|
|
207
79
|
}
|
|
80
|
+
return based._client;
|
|
208
81
|
}
|
|
209
|
-
async
|
|
210
|
-
var _a;
|
|
82
|
+
async login(identifier, password) {
|
|
211
83
|
try {
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
|
223
95
|
});
|
|
224
|
-
|
|
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);
|
|
96
|
+
return response;
|
|
243
97
|
} catch (error) {
|
|
244
|
-
throw new Error(`
|
|
98
|
+
throw new Error(`Login failed: ${error.message}`);
|
|
245
99
|
}
|
|
246
100
|
}
|
|
247
|
-
async
|
|
101
|
+
async register(userData) {
|
|
248
102
|
try {
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
body: JSON.stringify({ email }),
|
|
252
|
-
methodName: "requestPasswordReset"
|
|
253
|
-
});
|
|
254
|
-
if (response.success) {
|
|
255
|
-
return response.data;
|
|
256
|
-
}
|
|
257
|
-
throw new Error(response.message);
|
|
103
|
+
const based = this._getBasedService("register");
|
|
104
|
+
return await based.call("users:register", userData);
|
|
258
105
|
} catch (error) {
|
|
259
|
-
throw new Error(`
|
|
106
|
+
throw new Error(`Registration failed: ${error.message}`);
|
|
260
107
|
}
|
|
261
108
|
}
|
|
262
|
-
async
|
|
109
|
+
async googleAuth(idToken) {
|
|
263
110
|
try {
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
body: JSON.stringify({ token, password }),
|
|
267
|
-
methodName: "confirmPasswordReset"
|
|
268
|
-
});
|
|
269
|
-
if (response.success) {
|
|
270
|
-
return response.data;
|
|
271
|
-
}
|
|
272
|
-
throw new Error(response.message);
|
|
111
|
+
const based = this._getBasedService("googleAuth");
|
|
112
|
+
return await based.call("users:google-auth", { idToken });
|
|
273
113
|
} catch (error) {
|
|
274
|
-
throw new Error(`
|
|
114
|
+
throw new Error(`Google auth failed: ${error.message}`);
|
|
275
115
|
}
|
|
276
116
|
}
|
|
277
|
-
async
|
|
117
|
+
async githubAuth(code) {
|
|
278
118
|
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);
|
|
119
|
+
const based = this._getBasedService("githubAuth");
|
|
120
|
+
return await based.call("users:github-auth", { code });
|
|
288
121
|
} catch (error) {
|
|
289
|
-
throw new Error(`
|
|
122
|
+
throw new Error(`GitHub auth failed: ${error.message}`);
|
|
290
123
|
}
|
|
291
124
|
}
|
|
292
|
-
async
|
|
293
|
-
this._requireReady("
|
|
294
|
-
try {
|
|
295
|
-
const response = await this._request("/auth/request-password-change", {
|
|
296
|
-
method: "POST",
|
|
297
|
-
methodName: "requestPasswordChange"
|
|
298
|
-
});
|
|
299
|
-
if (response.success) {
|
|
300
|
-
return response.data;
|
|
301
|
-
}
|
|
302
|
-
throw new Error(response.message);
|
|
303
|
-
} catch (error) {
|
|
304
|
-
throw new Error(`Password change request failed: ${error.message}`, { cause: error });
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
async confirmPasswordChange(currentPassword, newPassword, code) {
|
|
308
|
-
this._requireReady("confirmPasswordChange");
|
|
309
|
-
try {
|
|
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);
|
|
319
|
-
} catch (error) {
|
|
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;
|
|
343
|
-
}
|
|
344
|
-
return this._tokenManager.getAccessToken();
|
|
345
|
-
}
|
|
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");
|
|
125
|
+
async logout() {
|
|
126
|
+
this._requireReady("logout");
|
|
464
127
|
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);
|
|
128
|
+
const based = this._getBasedService("logout");
|
|
129
|
+
await based.call("logout");
|
|
130
|
+
this.updateContext({ authToken: null });
|
|
481
131
|
} catch (error) {
|
|
482
|
-
throw new Error(`
|
|
132
|
+
throw new Error(`Logout failed: ${error.message}`);
|
|
483
133
|
}
|
|
484
134
|
}
|
|
485
|
-
async
|
|
486
|
-
this._requireReady("
|
|
135
|
+
async updateUserRole(userId, newRole) {
|
|
136
|
+
this._requireReady("updateUserRole");
|
|
487
137
|
if (!userId) {
|
|
488
138
|
throw new Error("User ID is required");
|
|
489
139
|
}
|
|
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");
|
|
140
|
+
if (!this._userRoles.has(newRole)) {
|
|
141
|
+
throw new Error(`Invalid role: ${newRole}`);
|
|
507
142
|
}
|
|
508
143
|
try {
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
methodName: "getUserByEmail"
|
|
512
|
-
});
|
|
513
|
-
if (response.success) {
|
|
514
|
-
return response.data.user;
|
|
515
|
-
}
|
|
516
|
-
throw new Error(response.message);
|
|
144
|
+
const based = this._getBasedService("updateUserRole");
|
|
145
|
+
return await based.call("users:update-role", { userId, role: newRole });
|
|
517
146
|
} catch (error) {
|
|
518
|
-
throw new Error(`Failed to
|
|
147
|
+
throw new Error(`Failed to update user role: ${error.message}`);
|
|
519
148
|
}
|
|
520
149
|
}
|
|
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");
|
|
150
|
+
async updateProjectTier(projectId, newTier) {
|
|
151
|
+
this._requireReady("updateProjectTier");
|
|
528
152
|
if (!projectId) {
|
|
529
153
|
throw new Error("Project ID is required");
|
|
530
154
|
}
|
|
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;
|
|
155
|
+
if (!this._projectTiers.has(newTier)) {
|
|
156
|
+
throw new Error(`Invalid project tier: ${newTier}`);
|
|
577
157
|
}
|
|
578
158
|
try {
|
|
579
|
-
const
|
|
580
|
-
|
|
581
|
-
|
|
159
|
+
const based = this._getBasedService("updateProjectTier");
|
|
160
|
+
return await based.call("projects:update-tier", {
|
|
161
|
+
projectId,
|
|
162
|
+
tier: newTier
|
|
582
163
|
});
|
|
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
|
-
} catch (error) {
|
|
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;
|
|
690
|
-
}
|
|
691
|
-
return this._tokenManager.hasTokens() && this._tokenManager.isAccessTokenValid();
|
|
692
|
-
}
|
|
693
|
-
/**
|
|
694
|
-
* Helper method to get current user info
|
|
695
|
-
*/
|
|
696
|
-
async getCurrentUser() {
|
|
697
|
-
try {
|
|
698
|
-
return await this.getMe();
|
|
699
164
|
} catch (error) {
|
|
700
|
-
throw new Error(`Failed to
|
|
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");
|
|
165
|
+
throw new Error(`Failed to update project tier: ${error.message}`);
|
|
722
166
|
}
|
|
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
167
|
}
|
|
760
|
-
// ==================== PERMISSION METHODS (Existing) ====================
|
|
761
168
|
hasPermission(requiredPermission) {
|
|
762
169
|
var _a;
|
|
763
170
|
const authState = (_a = this._context) == null ? void 0 : _a.state;
|
|
@@ -806,17 +213,23 @@ class AuthService extends import_BaseService.BaseService {
|
|
|
806
213
|
if (!operationConfig) {
|
|
807
214
|
return false;
|
|
808
215
|
}
|
|
216
|
+
if (!operationConfig) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
809
219
|
const { permissions = [], features = [] } = operationConfig;
|
|
810
220
|
try {
|
|
811
221
|
const permissionResults = await Promise.all(
|
|
812
222
|
permissions.map(
|
|
813
|
-
(permission) => this.
|
|
223
|
+
(permission) => this.hasProjectPermission(projectId, permission)
|
|
814
224
|
)
|
|
815
225
|
);
|
|
816
226
|
const hasPermissions = requireAll ? permissionResults.every(Boolean) : permissionResults.some(Boolean);
|
|
817
227
|
if (!hasPermissions) {
|
|
818
228
|
return false;
|
|
819
229
|
}
|
|
230
|
+
if (!hasPermissions) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
820
233
|
if (checkFeatures && features.length > 0) {
|
|
821
234
|
const featureResults = features.map((feature) => {
|
|
822
235
|
const result = this.hasProjectFeature(projectId, feature);
|
|
@@ -826,6 +239,9 @@ class AuthService extends import_BaseService.BaseService {
|
|
|
826
239
|
if (!hasFeatures) {
|
|
827
240
|
return false;
|
|
828
241
|
}
|
|
242
|
+
if (!hasFeatures) {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
829
245
|
}
|
|
830
246
|
return true;
|
|
831
247
|
} catch (error) {
|
|
@@ -847,90 +263,200 @@ class AuthService extends import_BaseService.BaseService {
|
|
|
847
263
|
}
|
|
848
264
|
return action();
|
|
849
265
|
}
|
|
850
|
-
//
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
|
|
266
|
+
// Project access information
|
|
267
|
+
async getProjectAccess(projectId) {
|
|
268
|
+
this._requireReady();
|
|
269
|
+
if (!projectId) {
|
|
270
|
+
throw new Error("Project ID is required");
|
|
271
|
+
}
|
|
272
|
+
const operations = Object.keys(import_permission.PERMISSION_MAP);
|
|
273
|
+
const access = await Promise.all(
|
|
274
|
+
operations.map(async (operation) => {
|
|
275
|
+
const allowed = await this.canPerformOperation(projectId, operation);
|
|
276
|
+
const config = import_permission.PERMISSION_MAP[operation];
|
|
277
|
+
return {
|
|
278
|
+
operation,
|
|
279
|
+
allowed,
|
|
280
|
+
permissions: config.permissions,
|
|
281
|
+
features: config.features,
|
|
282
|
+
aiTokens: operation.startsWith("ai") ? this._getAITokens(projectId, operation.replace("ai", "")) : null
|
|
283
|
+
};
|
|
284
|
+
})
|
|
285
|
+
);
|
|
286
|
+
return {
|
|
287
|
+
projectId,
|
|
288
|
+
permissions: access.reduce(
|
|
289
|
+
(acc, { operation, ...details }) => ({
|
|
290
|
+
...acc,
|
|
291
|
+
[operation]: details
|
|
292
|
+
}),
|
|
293
|
+
{}
|
|
294
|
+
),
|
|
295
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
296
|
+
};
|
|
858
297
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
const
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
return
|
|
298
|
+
// AI token management
|
|
299
|
+
_getAITokens(projectId, featureType) {
|
|
300
|
+
const tokenFeatures = [
|
|
301
|
+
`ai${featureType}:3`,
|
|
302
|
+
`ai${featureType}:5`,
|
|
303
|
+
`ai${featureType}:15`
|
|
304
|
+
];
|
|
305
|
+
return tokenFeatures.reduce((total, feature) => {
|
|
306
|
+
const tokens = this.hasProjectFeature(projectId, feature);
|
|
307
|
+
return total + (typeof tokens === "number" ? tokens : 0);
|
|
308
|
+
}, 0);
|
|
309
|
+
}
|
|
310
|
+
async getProjectMembers(projectId) {
|
|
311
|
+
this._requireReady("getProjectMembers");
|
|
312
|
+
if (!projectId) {
|
|
313
|
+
throw new Error("Project ID is required");
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
const based = this._getBasedService("getProjectMembers");
|
|
317
|
+
return await based.call("projects:get-members", { projectId });
|
|
318
|
+
} catch (error) {
|
|
319
|
+
throw new Error(`Failed to get project members: ${error.message}`);
|
|
320
|
+
}
|
|
867
321
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
if (
|
|
871
|
-
|
|
322
|
+
async inviteMember(projectId, email, role, name, callbackUrl) {
|
|
323
|
+
this._requireReady("inviteMember");
|
|
324
|
+
if (!projectId) {
|
|
325
|
+
throw new Error("Project ID is required");
|
|
872
326
|
}
|
|
873
|
-
if (
|
|
874
|
-
|
|
327
|
+
if (!email) {
|
|
328
|
+
throw new Error("Email is required");
|
|
875
329
|
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
return this._cachePluginSession(optionSession);
|
|
330
|
+
if (!callbackUrl || Object.keys(callbackUrl).length === 0) {
|
|
331
|
+
throw new Error("Callback Url is required");
|
|
879
332
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
return this._cachePluginSession(contextSession);
|
|
333
|
+
if (!role || !this._userRoles.has(role)) {
|
|
334
|
+
throw new Error(`Invalid role: ${role}`);
|
|
883
335
|
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
if (stored) {
|
|
896
|
-
this._pluginSession = stored;
|
|
897
|
-
return stored;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
} catch {
|
|
901
|
-
}
|
|
336
|
+
try {
|
|
337
|
+
const based = this._getBasedService("inviteMember");
|
|
338
|
+
return await based.call("projects:invite-member", {
|
|
339
|
+
projectId,
|
|
340
|
+
email,
|
|
341
|
+
role,
|
|
342
|
+
name,
|
|
343
|
+
callbackUrl
|
|
344
|
+
});
|
|
345
|
+
} catch (error) {
|
|
346
|
+
throw new Error(`Failed to invite member: ${error.message}`);
|
|
902
347
|
}
|
|
903
|
-
return null;
|
|
904
348
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
if (window.localStorage) {
|
|
913
|
-
window.localStorage.setItem(PLUGIN_SESSION_STORAGE_KEY, session);
|
|
914
|
-
}
|
|
915
|
-
} catch {
|
|
916
|
-
}
|
|
349
|
+
async acceptInvite(token) {
|
|
350
|
+
this._requireReady("acceptInvite");
|
|
351
|
+
try {
|
|
352
|
+
const based = this._getBasedService("acceptInvite");
|
|
353
|
+
return await based.call("projects:accept-invite", { token });
|
|
354
|
+
} catch (error) {
|
|
355
|
+
throw new Error(`Failed to accept invite: ${error.message}`);
|
|
917
356
|
}
|
|
918
|
-
return session;
|
|
919
357
|
}
|
|
920
|
-
|
|
921
|
-
this.
|
|
358
|
+
async updateMemberRole(projectId, userId, role) {
|
|
359
|
+
this._requireReady("updateMemberRole");
|
|
360
|
+
if (!projectId) {
|
|
361
|
+
throw new Error("Project ID is required");
|
|
362
|
+
}
|
|
363
|
+
if (!userId) {
|
|
364
|
+
throw new Error("User ID is required");
|
|
365
|
+
}
|
|
366
|
+
if (!this._userRoles.has(role)) {
|
|
367
|
+
throw new Error(`Invalid role: ${role}`);
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
const based = this._getBasedService("updateMemberRole");
|
|
371
|
+
return await based.call("projects:update-member-role", {
|
|
372
|
+
projectId,
|
|
373
|
+
userId,
|
|
374
|
+
role
|
|
375
|
+
});
|
|
376
|
+
} catch (error) {
|
|
377
|
+
throw new Error(`Failed to update member role: ${error.message}`);
|
|
378
|
+
}
|
|
922
379
|
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
380
|
+
async removeMember(projectId, userId) {
|
|
381
|
+
this._requireReady("removeMember");
|
|
382
|
+
if (!projectId || !userId) {
|
|
383
|
+
throw new Error("Project ID and user ID are required");
|
|
384
|
+
}
|
|
385
|
+
try {
|
|
386
|
+
const based = this._getBasedService("removeMember");
|
|
387
|
+
return await based.call("projects:remove-member", { projectId, userId });
|
|
388
|
+
} catch (error) {
|
|
389
|
+
throw new Error(`Failed to remove member: ${error.message}`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
async confirmRegistration(token) {
|
|
393
|
+
try {
|
|
394
|
+
const based = this._getBasedService("confirmRegistration");
|
|
395
|
+
return await based.call("users:register-confirmation", { token });
|
|
396
|
+
} catch (error) {
|
|
397
|
+
throw new Error(`Registration confirmation failed: ${error.message}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
async requestPasswordReset(email, callbackUrl) {
|
|
401
|
+
try {
|
|
402
|
+
const based = this._getBasedService("requestPasswordReset");
|
|
403
|
+
return await based.call("users:reset-password", { email, callbackUrl });
|
|
404
|
+
} catch (error) {
|
|
405
|
+
throw new Error(`Password reset request failed: ${error.message}`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
async confirmPasswordReset(token, newPassword) {
|
|
409
|
+
try {
|
|
410
|
+
const based = this._getBasedService("confirmPasswordReset");
|
|
411
|
+
return await based.call("users:reset-password-confirm", {
|
|
412
|
+
token,
|
|
413
|
+
newPassword
|
|
414
|
+
});
|
|
415
|
+
} catch (error) {
|
|
416
|
+
throw new Error(`Password reset confirmation failed: ${error.message}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
async getStoredAuthState() {
|
|
420
|
+
try {
|
|
421
|
+
const based = this._getBasedService("getStoredAuthState");
|
|
422
|
+
const { authState } = based;
|
|
423
|
+
if (authState == null ? void 0 : authState.token) {
|
|
424
|
+
return {
|
|
425
|
+
userId: authState.userId,
|
|
426
|
+
authToken: authState.token,
|
|
427
|
+
projectRoles: authState.projectRoles,
|
|
428
|
+
globalRole: authState.globalRole,
|
|
429
|
+
error: null
|
|
430
|
+
};
|
|
933
431
|
}
|
|
432
|
+
return {
|
|
433
|
+
userId: false,
|
|
434
|
+
authToken: false
|
|
435
|
+
};
|
|
436
|
+
} catch (error) {
|
|
437
|
+
this._setError(error);
|
|
438
|
+
return {
|
|
439
|
+
userId: false,
|
|
440
|
+
authToken: false,
|
|
441
|
+
error: `Failed to get stored auth state: ${error.message}`
|
|
442
|
+
};
|
|
934
443
|
}
|
|
935
444
|
}
|
|
445
|
+
async subscribeToAuthChanges(callback) {
|
|
446
|
+
const based = this._getBasedService("subscribeToAuthChanges");
|
|
447
|
+
based.on("authstate-change", async (authState) => {
|
|
448
|
+
const formattedState = (authState == null ? void 0 : authState.token) ? {
|
|
449
|
+
userId: authState.userId,
|
|
450
|
+
authToken: authState.token,
|
|
451
|
+
projectRoles: authState.projectRoles,
|
|
452
|
+
globalRole: authState.globalRole,
|
|
453
|
+
error: null
|
|
454
|
+
} : {
|
|
455
|
+
userId: false,
|
|
456
|
+
authToken: false
|
|
457
|
+
};
|
|
458
|
+
await callback(formattedState);
|
|
459
|
+
});
|
|
460
|
+
return () => based.off("authstate-change");
|
|
461
|
+
}
|
|
936
462
|
}
|