@symbo.ls/sdk 2.32.5 → 2.32.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/services/AuthService.js +126 -14
- package/dist/cjs/services/FileService.js +6 -8
- package/dist/cjs/utils/changePreprocessor.js +4 -2
- package/dist/esm/index.js +136 -24
- package/dist/esm/services/AuthService.js +126 -14
- package/dist/esm/services/CollabService.js +4 -2
- package/dist/esm/services/FileService.js +6 -8
- package/dist/esm/services/ProjectService.js +4 -2
- package/dist/esm/services/index.js +136 -24
- package/dist/esm/utils/changePreprocessor.js +4 -2
- package/dist/node/services/AuthService.js +126 -14
- package/dist/node/services/FileService.js +6 -8
- package/dist/node/utils/changePreprocessor.js +4 -2
- package/package.json +6 -6
- package/src/services/AuthService.js +157 -14
- package/src/services/FileService.js +5 -8
- package/src/utils/changePreprocessor.js +6 -4
|
@@ -4,8 +4,10 @@ import {
|
|
|
4
4
|
TIER_FEATURES,
|
|
5
5
|
PROJECT_ROLE_PERMISSIONS
|
|
6
6
|
} from "../utils/permission.js";
|
|
7
|
+
const PLUGIN_SESSION_STORAGE_KEY = "plugin_auth_session";
|
|
7
8
|
class AuthService extends BaseService {
|
|
8
9
|
constructor(config) {
|
|
10
|
+
var _a, _b;
|
|
9
11
|
super(config);
|
|
10
12
|
this._userRoles = /* @__PURE__ */ new Set(["guest", "editor", "admin", "owner"]);
|
|
11
13
|
this._projectTiers = /* @__PURE__ */ new Set([
|
|
@@ -17,17 +19,28 @@ class AuthService extends BaseService {
|
|
|
17
19
|
]);
|
|
18
20
|
this._projectRoleCache = /* @__PURE__ */ new Map();
|
|
19
21
|
this._roleCacheExpiry = 5 * 60 * 1e3;
|
|
22
|
+
this._pluginSession = null;
|
|
23
|
+
this._resolvePluginSession(
|
|
24
|
+
(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
|
|
25
|
+
);
|
|
20
26
|
}
|
|
21
27
|
// Use BaseService.init/_request/_requireReady implementations
|
|
22
28
|
// ==================== AUTH METHODS ====================
|
|
23
|
-
async register(userData) {
|
|
29
|
+
async register(userData, options = {}) {
|
|
24
30
|
try {
|
|
31
|
+
const { payload, session } = this._preparePluginPayload(
|
|
32
|
+
{ ...userData || {} },
|
|
33
|
+
options.session
|
|
34
|
+
);
|
|
25
35
|
const response = await this._request("/auth/register", {
|
|
26
36
|
method: "POST",
|
|
27
|
-
body: JSON.stringify(
|
|
37
|
+
body: JSON.stringify(payload),
|
|
28
38
|
methodName: "register"
|
|
29
39
|
});
|
|
30
40
|
if (response.success) {
|
|
41
|
+
if (session) {
|
|
42
|
+
this._clearPluginSession(session);
|
|
43
|
+
}
|
|
31
44
|
return response.data;
|
|
32
45
|
}
|
|
33
46
|
throw new Error(response.message);
|
|
@@ -35,12 +48,19 @@ class AuthService extends BaseService {
|
|
|
35
48
|
throw new Error(`Registration failed: ${error.message}`, { cause: error });
|
|
36
49
|
}
|
|
37
50
|
}
|
|
38
|
-
async login(email, password) {
|
|
51
|
+
async login(email, password, options = {}) {
|
|
39
52
|
var _a;
|
|
40
53
|
try {
|
|
54
|
+
const { payload, session } = this._preparePluginPayload(
|
|
55
|
+
{
|
|
56
|
+
email,
|
|
57
|
+
password
|
|
58
|
+
},
|
|
59
|
+
options.session
|
|
60
|
+
);
|
|
41
61
|
const response = await this._request("/auth/login", {
|
|
42
62
|
method: "POST",
|
|
43
|
-
body: JSON.stringify(
|
|
63
|
+
body: JSON.stringify(payload),
|
|
44
64
|
methodName: "login"
|
|
45
65
|
});
|
|
46
66
|
if (response.success && response.data && response.data.tokens) {
|
|
@@ -56,6 +76,9 @@ class AuthService extends BaseService {
|
|
|
56
76
|
}
|
|
57
77
|
}
|
|
58
78
|
if (response.success) {
|
|
79
|
+
if (session) {
|
|
80
|
+
this._clearPluginSession(session);
|
|
81
|
+
}
|
|
59
82
|
return response.data;
|
|
60
83
|
}
|
|
61
84
|
throw new Error(response.message);
|
|
@@ -95,10 +118,10 @@ class AuthService extends BaseService {
|
|
|
95
118
|
throw new Error(`Token refresh failed: ${error.message}`, { cause: error });
|
|
96
119
|
}
|
|
97
120
|
}
|
|
98
|
-
async googleAuth(idToken, inviteToken = null) {
|
|
121
|
+
async googleAuth(idToken, inviteToken = null, options = {}) {
|
|
99
122
|
var _a;
|
|
100
123
|
try {
|
|
101
|
-
const payload = { idToken };
|
|
124
|
+
const { payload, session } = this._preparePluginPayload({ idToken }, options.session);
|
|
102
125
|
if (inviteToken) {
|
|
103
126
|
payload.inviteToken = inviteToken;
|
|
104
127
|
}
|
|
@@ -120,6 +143,9 @@ class AuthService extends BaseService {
|
|
|
120
143
|
}
|
|
121
144
|
}
|
|
122
145
|
if (response.success) {
|
|
146
|
+
if (session) {
|
|
147
|
+
this._clearPluginSession(session);
|
|
148
|
+
}
|
|
123
149
|
return response.data;
|
|
124
150
|
}
|
|
125
151
|
throw new Error(response.message);
|
|
@@ -127,10 +153,10 @@ class AuthService extends BaseService {
|
|
|
127
153
|
throw new Error(`Google auth failed: ${error.message}`, { cause: error });
|
|
128
154
|
}
|
|
129
155
|
}
|
|
130
|
-
async githubAuth(code, inviteToken = null) {
|
|
156
|
+
async githubAuth(code, inviteToken = null, options = {}) {
|
|
131
157
|
var _a;
|
|
132
158
|
try {
|
|
133
|
-
const payload = { code };
|
|
159
|
+
const { payload, session } = this._preparePluginPayload({ code }, options.session);
|
|
134
160
|
if (inviteToken) {
|
|
135
161
|
payload.inviteToken = inviteToken;
|
|
136
162
|
}
|
|
@@ -152,6 +178,9 @@ class AuthService extends BaseService {
|
|
|
152
178
|
}
|
|
153
179
|
}
|
|
154
180
|
if (response.success) {
|
|
181
|
+
if (session) {
|
|
182
|
+
this._clearPluginSession(session);
|
|
183
|
+
}
|
|
155
184
|
return response.data;
|
|
156
185
|
}
|
|
157
186
|
throw new Error(response.message);
|
|
@@ -159,10 +188,13 @@ class AuthService extends BaseService {
|
|
|
159
188
|
throw new Error(`GitHub auth failed: ${error.message}`, { cause: error });
|
|
160
189
|
}
|
|
161
190
|
}
|
|
162
|
-
async googleAuthCallback(code, redirectUri, inviteToken = null) {
|
|
191
|
+
async googleAuthCallback(code, redirectUri, inviteToken = null, options = {}) {
|
|
163
192
|
var _a;
|
|
164
193
|
try {
|
|
165
|
-
const
|
|
194
|
+
const { payload: body, session } = this._preparePluginPayload(
|
|
195
|
+
{ code, redirectUri },
|
|
196
|
+
options.session
|
|
197
|
+
);
|
|
166
198
|
if (inviteToken) {
|
|
167
199
|
body.inviteToken = inviteToken;
|
|
168
200
|
}
|
|
@@ -184,6 +216,9 @@ class AuthService extends BaseService {
|
|
|
184
216
|
}
|
|
185
217
|
}
|
|
186
218
|
if (response.success) {
|
|
219
|
+
if (session) {
|
|
220
|
+
this._clearPluginSession(session);
|
|
221
|
+
}
|
|
187
222
|
return response.data;
|
|
188
223
|
}
|
|
189
224
|
throw new Error(response.message);
|
|
@@ -667,17 +702,17 @@ class AuthService extends BaseService {
|
|
|
667
702
|
/**
|
|
668
703
|
* Helper method to register with validation
|
|
669
704
|
*/
|
|
670
|
-
async registerWithValidation(userData) {
|
|
705
|
+
async registerWithValidation(userData, options = {}) {
|
|
671
706
|
const validation = this.validateRegistrationData(userData);
|
|
672
707
|
if (!validation.isValid) {
|
|
673
708
|
throw new Error(`Validation failed: ${validation.errors.join(", ")}`);
|
|
674
709
|
}
|
|
675
|
-
return await this.register(userData);
|
|
710
|
+
return await this.register(userData, options);
|
|
676
711
|
}
|
|
677
712
|
/**
|
|
678
713
|
* Helper method to login with validation
|
|
679
714
|
*/
|
|
680
|
-
async loginWithValidation(email, password) {
|
|
715
|
+
async loginWithValidation(email, password, options = {}) {
|
|
681
716
|
if (!email || typeof email !== "string") {
|
|
682
717
|
throw new Error("Email is required and must be a string");
|
|
683
718
|
}
|
|
@@ -687,7 +722,7 @@ class AuthService extends BaseService {
|
|
|
687
722
|
if (!this._isValidEmail(email)) {
|
|
688
723
|
throw new Error("Email must be a valid email address");
|
|
689
724
|
}
|
|
690
|
-
return await this.login(email, password);
|
|
725
|
+
return await this.login(email, password, options);
|
|
691
726
|
}
|
|
692
727
|
/**
|
|
693
728
|
* Private helper to validate email format
|
|
@@ -795,6 +830,83 @@ class AuthService extends BaseService {
|
|
|
795
830
|
this._projectRoleCache.clear();
|
|
796
831
|
this._setReady(false);
|
|
797
832
|
}
|
|
833
|
+
_preparePluginPayload(payload, sessionOverride = null) {
|
|
834
|
+
const target = payload && typeof payload === "object" ? { ...payload } : {};
|
|
835
|
+
const session = this._resolvePluginSession(sessionOverride);
|
|
836
|
+
if (session && !Object.hasOwn(target, "session")) {
|
|
837
|
+
target.session = session;
|
|
838
|
+
return { payload: target, session };
|
|
839
|
+
}
|
|
840
|
+
return { payload: target, session: null };
|
|
841
|
+
}
|
|
842
|
+
_resolvePluginSession(sessionOverride = null) {
|
|
843
|
+
var _a, _b;
|
|
844
|
+
if (sessionOverride) {
|
|
845
|
+
return this._cachePluginSession(sessionOverride);
|
|
846
|
+
}
|
|
847
|
+
if (this._pluginSession) {
|
|
848
|
+
return this._pluginSession;
|
|
849
|
+
}
|
|
850
|
+
const optionSession = (_a = this._options) == null ? void 0 : _a.pluginSession;
|
|
851
|
+
if (optionSession) {
|
|
852
|
+
return this._cachePluginSession(optionSession);
|
|
853
|
+
}
|
|
854
|
+
const contextSession = (_b = this._context) == null ? void 0 : _b.pluginSession;
|
|
855
|
+
if (contextSession) {
|
|
856
|
+
return this._cachePluginSession(contextSession);
|
|
857
|
+
}
|
|
858
|
+
if (typeof window !== "undefined") {
|
|
859
|
+
try {
|
|
860
|
+
const sessionFromUrl = new URL(window.location.href).searchParams.get("session");
|
|
861
|
+
if (sessionFromUrl) {
|
|
862
|
+
return this._cachePluginSession(sessionFromUrl);
|
|
863
|
+
}
|
|
864
|
+
} catch {
|
|
865
|
+
}
|
|
866
|
+
try {
|
|
867
|
+
if (window.localStorage) {
|
|
868
|
+
const stored = window.localStorage.getItem(PLUGIN_SESSION_STORAGE_KEY);
|
|
869
|
+
if (stored) {
|
|
870
|
+
this._pluginSession = stored;
|
|
871
|
+
return stored;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
} catch {
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
return null;
|
|
878
|
+
}
|
|
879
|
+
_cachePluginSession(session) {
|
|
880
|
+
if (!session) {
|
|
881
|
+
return null;
|
|
882
|
+
}
|
|
883
|
+
this._pluginSession = session;
|
|
884
|
+
if (typeof window !== "undefined") {
|
|
885
|
+
try {
|
|
886
|
+
if (window.localStorage) {
|
|
887
|
+
window.localStorage.setItem(PLUGIN_SESSION_STORAGE_KEY, session);
|
|
888
|
+
}
|
|
889
|
+
} catch {
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
return session;
|
|
893
|
+
}
|
|
894
|
+
setPluginSession(session) {
|
|
895
|
+
this._cachePluginSession(session);
|
|
896
|
+
}
|
|
897
|
+
_clearPluginSession(session = null) {
|
|
898
|
+
if (!session || this._pluginSession === session) {
|
|
899
|
+
this._pluginSession = null;
|
|
900
|
+
}
|
|
901
|
+
if (typeof window !== "undefined") {
|
|
902
|
+
try {
|
|
903
|
+
if (window.localStorage) {
|
|
904
|
+
window.localStorage.removeItem(PLUGIN_SESSION_STORAGE_KEY);
|
|
905
|
+
}
|
|
906
|
+
} catch {
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
798
910
|
}
|
|
799
911
|
export {
|
|
800
912
|
AuthService
|
|
@@ -2,14 +2,17 @@ import { BaseService } from "./BaseService.js";
|
|
|
2
2
|
class FileService extends BaseService {
|
|
3
3
|
// ==================== FILE METHODS ====================
|
|
4
4
|
async uploadFile(file, options = {}) {
|
|
5
|
+
var _a;
|
|
5
6
|
this._requireReady("uploadFile");
|
|
6
7
|
if (!file) {
|
|
7
8
|
throw new Error("File is required for upload");
|
|
8
9
|
}
|
|
9
10
|
const formData = new FormData();
|
|
10
11
|
formData.append("file", file);
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
const hasProjectIdOption = Object.hasOwn(options, "projectId");
|
|
13
|
+
const projectId = hasProjectIdOption ? options.projectId : (_a = this._context.project) == null ? void 0 : _a.id;
|
|
14
|
+
if (projectId != null && projectId !== "") {
|
|
15
|
+
formData.append("projectId", projectId);
|
|
13
16
|
}
|
|
14
17
|
if (options.tags) {
|
|
15
18
|
formData.append("tags", JSON.stringify(options.tags));
|
|
@@ -31,12 +34,7 @@ class FileService extends BaseService {
|
|
|
31
34
|
if (!response.success) {
|
|
32
35
|
throw new Error(response.message);
|
|
33
36
|
}
|
|
34
|
-
return
|
|
35
|
-
id: response.data.id,
|
|
36
|
-
src: `${this._apiUrl}/core/files/public/${response.data.id}/download`,
|
|
37
|
-
success: true,
|
|
38
|
-
message: response.message
|
|
39
|
-
};
|
|
37
|
+
return response.data;
|
|
40
38
|
} catch (error) {
|
|
41
39
|
throw new Error(`File upload failed: ${error.message}`, { cause: error });
|
|
42
40
|
}
|
|
@@ -17,11 +17,12 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
17
17
|
const expandTuple = (t) => {
|
|
18
18
|
const [action, path, value] = t || [];
|
|
19
19
|
const isSchemaPath = Array.isArray(path) && path[0] === "schema";
|
|
20
|
+
const isFilesPath = Array.isArray(path) && path[0] === "files";
|
|
20
21
|
if (action === "delete") {
|
|
21
22
|
return [t];
|
|
22
23
|
}
|
|
23
24
|
const canConsiderExpansion = action === "update" && Array.isArray(path) && (path.length === 1 || path.length === 2 || isSchemaPath && path.length === 3) && isPlainObject(value);
|
|
24
|
-
if (!canConsiderExpansion) {
|
|
25
|
+
if (!canConsiderExpansion || isFilesPath || value && value.type === "files") {
|
|
25
26
|
return [t];
|
|
26
27
|
}
|
|
27
28
|
const prev = getByPathSafe(root, path) || {};
|
|
@@ -87,7 +88,8 @@ function preprocessChanges(root, tuples = [], options = {}) {
|
|
|
87
88
|
continue;
|
|
88
89
|
}
|
|
89
90
|
const [action, path, value] = t;
|
|
90
|
-
|
|
91
|
+
const isFilesPath = Array.isArray(path) && path[0] === "files";
|
|
92
|
+
if (action !== "update" || !Array.isArray(path) || path.length !== 1 && path.length !== 2 || !isPlainObject(value) || isFilesPath || value && value.type === "files") {
|
|
91
93
|
continue;
|
|
92
94
|
}
|
|
93
95
|
const keys = Object.keys(value).filter((k) => k !== "__order");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/sdk",
|
|
3
|
-
"version": "2.32.
|
|
3
|
+
"version": "2.32.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"test:user": "cross-env NODE_ENV=$NODE_ENV npx tape integration-tests/index.js integration-tests/user/*.test.js | tap-spec"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@domql/element": "^2.32.
|
|
50
|
-
"@domql/utils": "^2.32.
|
|
51
|
-
"@symbo.ls/router": "^2.32.
|
|
52
|
-
"@symbo.ls/socket": "^2.32.
|
|
49
|
+
"@domql/element": "^2.32.7",
|
|
50
|
+
"@domql/utils": "^2.32.7",
|
|
51
|
+
"@symbo.ls/router": "^2.32.7",
|
|
52
|
+
"@symbo.ls/socket": "^2.32.7",
|
|
53
53
|
"acorn": "^8.14.0",
|
|
54
54
|
"acorn-walk": "^8.3.4",
|
|
55
55
|
"dexie": "^4.0.11",
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"tap-spec": "^5.0.0",
|
|
72
72
|
"tape": "^5.9.0"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "c99355e8e88604af8376bebbf553e559c3f2db76"
|
|
75
75
|
}
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
PROJECT_ROLE_PERMISSIONS
|
|
6
6
|
} from '../utils/permission.js'
|
|
7
7
|
|
|
8
|
+
const PLUGIN_SESSION_STORAGE_KEY = 'plugin_auth_session'
|
|
9
|
+
|
|
8
10
|
export class AuthService extends BaseService {
|
|
9
11
|
constructor(config) {
|
|
10
12
|
super(config)
|
|
@@ -18,20 +20,37 @@ export class AuthService extends BaseService {
|
|
|
18
20
|
])
|
|
19
21
|
this._projectRoleCache = new Map() // Cache for project roles
|
|
20
22
|
this._roleCacheExpiry = 5 * 60 * 1000 // 5 minutes cache expiry
|
|
23
|
+
this._pluginSession = null
|
|
24
|
+
|
|
25
|
+
this._resolvePluginSession(
|
|
26
|
+
config?.session ||
|
|
27
|
+
config?.pluginSession ||
|
|
28
|
+
config?.options?.pluginSession ||
|
|
29
|
+
config?.context?.pluginSession ||
|
|
30
|
+
null
|
|
31
|
+
)
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
// Use BaseService.init/_request/_requireReady implementations
|
|
24
35
|
|
|
25
36
|
// ==================== AUTH METHODS ====================
|
|
26
37
|
|
|
27
|
-
async register(userData) {
|
|
38
|
+
async register(userData, options = {}) {
|
|
28
39
|
try {
|
|
40
|
+
const { payload, session } = this._preparePluginPayload(
|
|
41
|
+
{ ...(userData || {}) },
|
|
42
|
+
options.session
|
|
43
|
+
)
|
|
44
|
+
|
|
29
45
|
const response = await this._request('/auth/register', {
|
|
30
46
|
method: 'POST',
|
|
31
|
-
body: JSON.stringify(
|
|
47
|
+
body: JSON.stringify(payload),
|
|
32
48
|
methodName: 'register'
|
|
33
49
|
})
|
|
34
50
|
if (response.success) {
|
|
51
|
+
if (session) {
|
|
52
|
+
this._clearPluginSession(session)
|
|
53
|
+
}
|
|
35
54
|
return response.data
|
|
36
55
|
}
|
|
37
56
|
throw new Error(response.message)
|
|
@@ -40,11 +59,19 @@ export class AuthService extends BaseService {
|
|
|
40
59
|
}
|
|
41
60
|
}
|
|
42
61
|
|
|
43
|
-
async login(email, password) {
|
|
62
|
+
async login(email, password, options = {}) {
|
|
44
63
|
try {
|
|
64
|
+
const { payload, session } = this._preparePluginPayload(
|
|
65
|
+
{
|
|
66
|
+
email,
|
|
67
|
+
password
|
|
68
|
+
},
|
|
69
|
+
options.session
|
|
70
|
+
)
|
|
71
|
+
|
|
45
72
|
const response = await this._request('/auth/login', {
|
|
46
73
|
method: 'POST',
|
|
47
|
-
body: JSON.stringify(
|
|
74
|
+
body: JSON.stringify(payload),
|
|
48
75
|
methodName: 'login'
|
|
49
76
|
})
|
|
50
77
|
|
|
@@ -65,6 +92,9 @@ export class AuthService extends BaseService {
|
|
|
65
92
|
}
|
|
66
93
|
|
|
67
94
|
if (response.success) {
|
|
95
|
+
if (session) {
|
|
96
|
+
this._clearPluginSession(session)
|
|
97
|
+
}
|
|
68
98
|
return response.data
|
|
69
99
|
}
|
|
70
100
|
throw new Error(response.message)
|
|
@@ -112,9 +142,9 @@ export class AuthService extends BaseService {
|
|
|
112
142
|
}
|
|
113
143
|
}
|
|
114
144
|
|
|
115
|
-
async googleAuth(idToken, inviteToken = null) {
|
|
145
|
+
async googleAuth(idToken, inviteToken = null, options = {}) {
|
|
116
146
|
try {
|
|
117
|
-
const payload = { idToken }
|
|
147
|
+
const { payload, session } = this._preparePluginPayload({ idToken }, options.session)
|
|
118
148
|
if (inviteToken) {
|
|
119
149
|
payload.inviteToken = inviteToken
|
|
120
150
|
}
|
|
@@ -142,6 +172,9 @@ export class AuthService extends BaseService {
|
|
|
142
172
|
}
|
|
143
173
|
|
|
144
174
|
if (response.success) {
|
|
175
|
+
if (session) {
|
|
176
|
+
this._clearPluginSession(session)
|
|
177
|
+
}
|
|
145
178
|
return response.data
|
|
146
179
|
}
|
|
147
180
|
throw new Error(response.message)
|
|
@@ -150,9 +183,9 @@ export class AuthService extends BaseService {
|
|
|
150
183
|
}
|
|
151
184
|
}
|
|
152
185
|
|
|
153
|
-
async githubAuth(code, inviteToken = null) {
|
|
186
|
+
async githubAuth(code, inviteToken = null, options = {}) {
|
|
154
187
|
try {
|
|
155
|
-
const payload = { code }
|
|
188
|
+
const { payload, session } = this._preparePluginPayload({ code }, options.session)
|
|
156
189
|
if (inviteToken) {
|
|
157
190
|
payload.inviteToken = inviteToken
|
|
158
191
|
}
|
|
@@ -180,6 +213,9 @@ export class AuthService extends BaseService {
|
|
|
180
213
|
}
|
|
181
214
|
|
|
182
215
|
if (response.success) {
|
|
216
|
+
if (session) {
|
|
217
|
+
this._clearPluginSession(session)
|
|
218
|
+
}
|
|
183
219
|
return response.data
|
|
184
220
|
}
|
|
185
221
|
throw new Error(response.message)
|
|
@@ -188,9 +224,12 @@ export class AuthService extends BaseService {
|
|
|
188
224
|
}
|
|
189
225
|
}
|
|
190
226
|
|
|
191
|
-
async googleAuthCallback (code, redirectUri, inviteToken = null) {
|
|
227
|
+
async googleAuthCallback (code, redirectUri, inviteToken = null, options = {}) {
|
|
192
228
|
try {
|
|
193
|
-
const
|
|
229
|
+
const { payload: body, session } = this._preparePluginPayload(
|
|
230
|
+
{ code, redirectUri },
|
|
231
|
+
options.session
|
|
232
|
+
)
|
|
194
233
|
if (inviteToken) {
|
|
195
234
|
body.inviteToken = inviteToken
|
|
196
235
|
}
|
|
@@ -218,6 +257,9 @@ export class AuthService extends BaseService {
|
|
|
218
257
|
}
|
|
219
258
|
|
|
220
259
|
if (response.success) {
|
|
260
|
+
if (session) {
|
|
261
|
+
this._clearPluginSession(session)
|
|
262
|
+
}
|
|
221
263
|
return response.data
|
|
222
264
|
}
|
|
223
265
|
throw new Error(response.message)
|
|
@@ -787,19 +829,19 @@ export class AuthService extends BaseService {
|
|
|
787
829
|
/**
|
|
788
830
|
* Helper method to register with validation
|
|
789
831
|
*/
|
|
790
|
-
async registerWithValidation(userData) {
|
|
832
|
+
async registerWithValidation(userData, options = {}) {
|
|
791
833
|
const validation = this.validateRegistrationData(userData)
|
|
792
834
|
if (!validation.isValid) {
|
|
793
835
|
throw new Error(`Validation failed: ${validation.errors.join(', ')}`)
|
|
794
836
|
}
|
|
795
837
|
|
|
796
|
-
return await this.register(userData)
|
|
838
|
+
return await this.register(userData, options)
|
|
797
839
|
}
|
|
798
840
|
|
|
799
841
|
/**
|
|
800
842
|
* Helper method to login with validation
|
|
801
843
|
*/
|
|
802
|
-
async loginWithValidation(email, password) {
|
|
844
|
+
async loginWithValidation(email, password, options = {}) {
|
|
803
845
|
if (!email || typeof email !== 'string') {
|
|
804
846
|
throw new Error('Email is required and must be a string')
|
|
805
847
|
}
|
|
@@ -812,7 +854,7 @@ export class AuthService extends BaseService {
|
|
|
812
854
|
throw new Error('Email must be a valid email address')
|
|
813
855
|
}
|
|
814
856
|
|
|
815
|
-
return await this.login(email, password)
|
|
857
|
+
return await this.login(email, password, options)
|
|
816
858
|
}
|
|
817
859
|
|
|
818
860
|
/**
|
|
@@ -952,4 +994,105 @@ export class AuthService extends BaseService {
|
|
|
952
994
|
this._projectRoleCache.clear()
|
|
953
995
|
this._setReady(false)
|
|
954
996
|
}
|
|
997
|
+
|
|
998
|
+
_preparePluginPayload(payload, sessionOverride = null) {
|
|
999
|
+
const target =
|
|
1000
|
+
payload && typeof payload === 'object'
|
|
1001
|
+
? { ...payload }
|
|
1002
|
+
: {}
|
|
1003
|
+
|
|
1004
|
+
const session = this._resolvePluginSession(sessionOverride)
|
|
1005
|
+
|
|
1006
|
+
if (session && !Object.hasOwn(target, 'session')) {
|
|
1007
|
+
target.session = session
|
|
1008
|
+
return { payload: target, session }
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
return { payload: target, session: null }
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
_resolvePluginSession(sessionOverride = null) {
|
|
1015
|
+
if (sessionOverride) {
|
|
1016
|
+
return this._cachePluginSession(sessionOverride)
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
if (this._pluginSession) {
|
|
1020
|
+
return this._pluginSession
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
const optionSession = this._options?.pluginSession
|
|
1024
|
+
if (optionSession) {
|
|
1025
|
+
return this._cachePluginSession(optionSession)
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
const contextSession = this._context?.pluginSession
|
|
1029
|
+
if (contextSession) {
|
|
1030
|
+
return this._cachePluginSession(contextSession)
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
if (typeof window !== 'undefined') {
|
|
1034
|
+
try {
|
|
1035
|
+
const sessionFromUrl = new URL(window.location.href).searchParams.get('session')
|
|
1036
|
+
if (sessionFromUrl) {
|
|
1037
|
+
return this._cachePluginSession(sessionFromUrl)
|
|
1038
|
+
}
|
|
1039
|
+
} catch {
|
|
1040
|
+
// Ignore URL parsing errors
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
try {
|
|
1044
|
+
if (window.localStorage) {
|
|
1045
|
+
const stored = window.localStorage.getItem(PLUGIN_SESSION_STORAGE_KEY)
|
|
1046
|
+
if (stored) {
|
|
1047
|
+
this._pluginSession = stored
|
|
1048
|
+
return stored
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
} catch {
|
|
1052
|
+
// Ignore storage access issues
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
return null
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
_cachePluginSession(session) {
|
|
1060
|
+
if (!session) {
|
|
1061
|
+
return null
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
this._pluginSession = session
|
|
1065
|
+
|
|
1066
|
+
if (typeof window !== 'undefined') {
|
|
1067
|
+
try {
|
|
1068
|
+
if (window.localStorage) {
|
|
1069
|
+
window.localStorage.setItem(PLUGIN_SESSION_STORAGE_KEY, session)
|
|
1070
|
+
}
|
|
1071
|
+
} catch {
|
|
1072
|
+
// Ignore storage access issues
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
return session
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
setPluginSession(session) {
|
|
1080
|
+
this._cachePluginSession(session)
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
_clearPluginSession(session = null) {
|
|
1084
|
+
if (!session || this._pluginSession === session) {
|
|
1085
|
+
this._pluginSession = null
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
if (typeof window !== 'undefined') {
|
|
1089
|
+
try {
|
|
1090
|
+
if (window.localStorage) {
|
|
1091
|
+
window.localStorage.removeItem(PLUGIN_SESSION_STORAGE_KEY)
|
|
1092
|
+
}
|
|
1093
|
+
} catch {
|
|
1094
|
+
// Ignore storage access issues
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
955
1098
|
}
|
|
@@ -13,8 +13,10 @@ export class FileService extends BaseService {
|
|
|
13
13
|
formData.append('file', file)
|
|
14
14
|
|
|
15
15
|
// Add optional parameters only if they exist
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const hasProjectIdOption = Object.hasOwn(options, 'projectId')
|
|
17
|
+
const projectId = hasProjectIdOption ? options.projectId : this._context.project?.id
|
|
18
|
+
if (projectId != null && projectId !== '') {
|
|
19
|
+
formData.append('projectId', projectId)
|
|
18
20
|
}
|
|
19
21
|
if (options.tags) {
|
|
20
22
|
formData.append('tags', JSON.stringify(options.tags))
|
|
@@ -38,12 +40,7 @@ export class FileService extends BaseService {
|
|
|
38
40
|
throw new Error(response.message)
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
return
|
|
42
|
-
id: response.data.id,
|
|
43
|
-
src: `${this._apiUrl}/core/files/public/${response.data.id}/download`,
|
|
44
|
-
success: true,
|
|
45
|
-
message: response.message
|
|
46
|
-
}
|
|
43
|
+
return response.data
|
|
47
44
|
} catch (error) {
|
|
48
45
|
throw new Error(`File upload failed: ${error.message}`, { cause: error })
|
|
49
46
|
}
|
|
@@ -25,6 +25,7 @@ export function preprocessChanges (root, tuples = [], options = {}) {
|
|
|
25
25
|
const expandTuple = (t) => {
|
|
26
26
|
const [action, path, value] = t || []
|
|
27
27
|
const isSchemaPath = Array.isArray(path) && path[0] === 'schema'
|
|
28
|
+
const isFilesPath = Array.isArray(path) && path[0] === 'files'
|
|
28
29
|
if (action === 'delete') { return [t] }
|
|
29
30
|
|
|
30
31
|
const canConsiderExpansion = (
|
|
@@ -37,7 +38,7 @@ export function preprocessChanges (root, tuples = [], options = {}) {
|
|
|
37
38
|
) &&
|
|
38
39
|
isPlainObject(value)
|
|
39
40
|
)
|
|
40
|
-
if (!canConsiderExpansion) { return [t] }
|
|
41
|
+
if (!canConsiderExpansion || isFilesPath || (value && value.type === 'files')) { return [t] }
|
|
41
42
|
|
|
42
43
|
const prev = getByPathSafe(root, path) || {}
|
|
43
44
|
const next = value || {}
|
|
@@ -108,11 +109,14 @@ export function preprocessChanges (root, tuples = [], options = {}) {
|
|
|
108
109
|
continue
|
|
109
110
|
}
|
|
110
111
|
const [action, path, value] = t
|
|
112
|
+
const isFilesPath = Array.isArray(path) && path[0] === 'files'
|
|
111
113
|
if (
|
|
112
114
|
action !== 'update' ||
|
|
113
115
|
!Array.isArray(path) ||
|
|
114
116
|
(path.length !== 1 && path.length !== 2) ||
|
|
115
|
-
!isPlainObject(value)
|
|
117
|
+
!isPlainObject(value) ||
|
|
118
|
+
isFilesPath ||
|
|
119
|
+
(value && value.type === 'files')
|
|
116
120
|
) {
|
|
117
121
|
// eslint-disable-next-line no-continue
|
|
118
122
|
continue
|
|
@@ -135,5 +139,3 @@ export function preprocessChanges (root, tuples = [], options = {}) {
|
|
|
135
139
|
|
|
136
140
|
return { granularChanges, orders: mergedOrders }
|
|
137
141
|
}
|
|
138
|
-
|
|
139
|
-
|