@memberjunction/server 5.28.0 → 5.30.0
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/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +63 -70
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/config.d.ts +151 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +15 -0
- package/dist/config.js.map +1 -1
- package/dist/generated/generated.d.ts +452 -6
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +2788 -303
- package/dist/generated/generated.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/resolvers/FeedbackResolver.d.ts +150 -0
- package/dist/resolvers/FeedbackResolver.d.ts.map +1 -0
- package/dist/resolvers/FeedbackResolver.js +876 -0
- package/dist/resolvers/FeedbackResolver.js.map +1 -0
- package/dist/resolvers/FileResolver.d.ts +27 -0
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +32 -3
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +100 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +532 -41
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts +77 -0
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +300 -1
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +87 -32
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +20 -12
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +20 -9
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +153 -116
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/services/TaskOrchestrator.d.ts.map +1 -1
- package/dist/services/TaskOrchestrator.js +78 -79
- package/dist/services/TaskOrchestrator.js.map +1 -1
- package/package.json +68 -66
- package/src/auth/newUsers.ts +65 -74
- package/src/config.ts +19 -0
- package/src/generated/generated.ts +1753 -40
- package/src/index.ts +1 -0
- package/src/resolvers/FeedbackResolver.ts +940 -0
- package/src/resolvers/FileResolver.ts +33 -4
- package/src/resolvers/IntegrationDiscoveryResolver.ts +543 -43
- package/src/resolvers/MCPResolver.ts +297 -1
- package/src/resolvers/RunAIAgentResolver.ts +89 -32
- package/src/resolvers/SyncDataResolver.ts +24 -14
- package/src/resolvers/SyncRolesUsersResolver.ts +177 -141
- package/src/services/TaskOrchestrator.ts +86 -93
package/src/auth/newUsers.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApplicationInfo, EntitySaveOptions, LogError, LogStatus, Metadata, RunView, RunViewResult, UserInfo } from "@memberjunction/core";
|
|
1
|
+
import { ApplicationInfo, DatabaseProviderBase, EntitySaveOptions, LogError, LogStatus, Metadata, RunView, RunViewResult, UserInfo } from "@memberjunction/core";
|
|
2
2
|
import { RegisterClass } from "@memberjunction/global";
|
|
3
3
|
import { UserCache } from "@memberjunction/sqlserver-dataprovider";
|
|
4
4
|
import { configInfo } from "../config.js";
|
|
@@ -43,81 +43,72 @@ export class NewUserBase {
|
|
|
43
43
|
user.LinkedEntityRecordID = linkedEntityRecordId;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
// Create the user and all of its role/application/app-entity records atomically.
|
|
47
|
+
// If any Save fails partway through, the whole provisioning rolls back so we never
|
|
48
|
+
// leave a half-created user with partial roles/applications behind.
|
|
49
|
+
const provider = Metadata.Provider as DatabaseProviderBase;
|
|
50
|
+
await provider.BeginTransaction();
|
|
51
|
+
try {
|
|
52
|
+
if (!await user.Save()) {
|
|
53
|
+
throw new Error(`Failed to create new user ${firstName} ${lastName} ${email}: ${user.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
54
|
+
}
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (!userRole) {
|
|
62
|
-
LogError(`Role ${role} not found in the database, cannot assign to new user ${user.Name}`);
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
56
|
+
if(configInfo.userHandling && configInfo.userHandling.newUserRoles){
|
|
57
|
+
LogStatus(`User ${user.Email} created, assigning roles`);
|
|
58
|
+
for (const role of configInfo.userHandling.newUserRoles) {
|
|
59
|
+
const userRole = md.Roles.find(r => r.Name === role);
|
|
60
|
+
if (!userRole) {
|
|
61
|
+
LogError(`Role ${role} not found in the database, cannot assign to new user ${user.Name}`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
const userRoleEntity: MJUserRoleEntity = await md.GetEntityObject<MJUserRoleEntity>('MJ: User Roles', contextUser);
|
|
66
|
+
userRoleEntity.NewRecord();
|
|
67
|
+
userRoleEntity.UserID = user.ID;
|
|
68
|
+
userRoleEntity.RoleID = userRole.ID;
|
|
69
|
+
if (!await userRoleEntity.Save()) {
|
|
70
|
+
throw new Error(`Failed to assign role ${role} to new user ${user.Name}: ${userRoleEntity.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
71
|
+
}
|
|
69
72
|
LogStatus(`Assigned role ${role} to new user ${user.Name}`);
|
|
70
73
|
}
|
|
71
|
-
else{
|
|
72
|
-
LogError(`Failed to assign role ${role} to new user ${user.Name}:`, undefined, userRoleEntity.LatestResult);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
74
|
}
|
|
76
|
-
}
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (application) {
|
|
93
|
-
applicationsToCreate.push(application);
|
|
94
|
-
} else {
|
|
95
|
-
LogError(`Application ${appName} not found in the Metadata, cannot assign to new user ${user.Name}`);
|
|
76
|
+
if (configInfo.userHandling && configInfo.userHandling.CreateUserApplicationRecords) {
|
|
77
|
+
LogStatus("Creating User Applications for new user: " + user.Name);
|
|
78
|
+
|
|
79
|
+
let applicationsToCreate: ApplicationInfo[] = [];
|
|
80
|
+
|
|
81
|
+
if (configInfo.userHandling.UserApplications && configInfo.userHandling.UserApplications.length > 0) {
|
|
82
|
+
for (const appName of configInfo.userHandling.UserApplications) {
|
|
83
|
+
const toLowerCase: string = appName.trim().toLocaleLowerCase();
|
|
84
|
+
const application: ApplicationInfo | undefined = md.Applications.find(a => a.Name.trim().toLocaleLowerCase() === toLowerCase);
|
|
85
|
+
if (application) {
|
|
86
|
+
applicationsToCreate.push(application);
|
|
87
|
+
} else {
|
|
88
|
+
LogError(`Application ${appName} not found in the Metadata, cannot assign to new user ${user.Name}`);
|
|
89
|
+
}
|
|
96
90
|
}
|
|
91
|
+
} else {
|
|
92
|
+
LogStatus(`No UserApplications configured, using DefaultForNewUser applications for new user ${user.Name}`);
|
|
93
|
+
applicationsToCreate = md.Applications
|
|
94
|
+
.filter(a => a.DefaultForNewUser)
|
|
95
|
+
.sort((a, b) => (a.DefaultSequence ?? 100) - (b.DefaultSequence ?? 100));
|
|
96
|
+
LogStatus(`Found ${applicationsToCreate.length} applications with DefaultForNewUser=true`);
|
|
97
97
|
}
|
|
98
|
-
} else {
|
|
99
|
-
// Fall back to DefaultForNewUser applications from metadata, sorted by DefaultSequence
|
|
100
|
-
LogStatus(`No UserApplications configured, using DefaultForNewUser applications for new user ${user.Name}`);
|
|
101
|
-
applicationsToCreate = md.Applications
|
|
102
|
-
.filter(a => a.DefaultForNewUser)
|
|
103
|
-
.sort((a, b) => (a.DefaultSequence ?? 100) - (b.DefaultSequence ?? 100));
|
|
104
|
-
LogStatus(`Found ${applicationsToCreate.length} applications with DefaultForNewUser=true`);
|
|
105
|
-
}
|
|
106
98
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
99
|
+
for (const [appIndex, application] of applicationsToCreate.entries()) {
|
|
100
|
+
const userApplication: MJUserApplicationEntity = await md.GetEntityObject<MJUserApplicationEntity>('MJ: User Applications', contextUser);
|
|
101
|
+
userApplication.NewRecord();
|
|
102
|
+
userApplication.UserID = user.ID;
|
|
103
|
+
userApplication.ApplicationID = application.ID;
|
|
104
|
+
userApplication.Sequence = appIndex;
|
|
105
|
+
userApplication.IsActive = true;
|
|
106
|
+
|
|
107
|
+
if (!await userApplication.Save()) {
|
|
108
|
+
throw new Error(`Failed to create User Application ${application.Name} for new user ${user.Name}: ${userApplication.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
109
|
+
}
|
|
118
110
|
LogStatus(`Created User Application ${application.Name} for new user ${user.Name}`);
|
|
119
111
|
|
|
120
|
-
//now create a MJUserApplicationEntity records for each entity in the application
|
|
121
112
|
const rv: RunView = new RunView();
|
|
122
113
|
const rvResult: RunViewResult<MJApplicationEntityEntityType> = await rv.RunView({
|
|
123
114
|
EntityName: 'MJ: Application Entities',
|
|
@@ -138,19 +129,19 @@ export class NewUserBase {
|
|
|
138
129
|
userAppEntity.EntityID = appEntity.EntityID;
|
|
139
130
|
userAppEntity.Sequence = index;
|
|
140
131
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
LogStatus(`Created User Application Entity ${appEntity.Entity} for new user ${user.Name}`);
|
|
144
|
-
}
|
|
145
|
-
else{
|
|
146
|
-
LogError(`Failed to create User Application Entity for new user ${user.Name}:`, undefined, userAppEntity.LatestResult);
|
|
132
|
+
if (!await userAppEntity.Save()) {
|
|
133
|
+
throw new Error(`Failed to create User Application Entity for new user ${user.Name}: ${userAppEntity.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
147
134
|
}
|
|
135
|
+
LogStatus(`Created User Application Entity ${appEntity.Entity} for new user ${user.Name}`);
|
|
148
136
|
}
|
|
149
137
|
}
|
|
150
|
-
else{
|
|
151
|
-
LogError(`Failed to create User Application ${application.Name} for new user ${user.Name}:`, undefined, userApplication.LatestResult);
|
|
152
|
-
}
|
|
153
138
|
}
|
|
139
|
+
|
|
140
|
+
await provider.CommitTransaction();
|
|
141
|
+
} catch (txErr) {
|
|
142
|
+
await provider.RollbackTransaction();
|
|
143
|
+
LogError(txErr);
|
|
144
|
+
return null;
|
|
154
145
|
}
|
|
155
146
|
|
|
156
147
|
return user;
|
package/src/config.ts
CHANGED
|
@@ -205,6 +205,22 @@ const cacheSettingsSchema = z.object({
|
|
|
205
205
|
verboseLogging: z.boolean().optional().default(false),
|
|
206
206
|
});
|
|
207
207
|
|
|
208
|
+
const feedbackGithubSettingsSchema = z.object({
|
|
209
|
+
owner: z.string().optional(),
|
|
210
|
+
repo: z.string().optional(),
|
|
211
|
+
defaultLabels: z.array(z.string()).optional(),
|
|
212
|
+
categoryLabels: z.record(z.string()).optional(),
|
|
213
|
+
severityLabels: z.record(z.string()).optional(),
|
|
214
|
+
assignees: z.array(z.string()).optional(),
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const feedbackSettingsSchema = z.object({
|
|
218
|
+
/** Org-level kill switch for the in-app feedback feature. Defaults to true (enabled). */
|
|
219
|
+
enabled: z.boolean().optional().default(true),
|
|
220
|
+
/** Optional GitHub-specific settings used by the feedback resolver. */
|
|
221
|
+
github: feedbackGithubSettingsSchema.optional(),
|
|
222
|
+
});
|
|
223
|
+
|
|
208
224
|
const configInfoSchema = z.object({
|
|
209
225
|
userHandling: userHandlingInfoSchema,
|
|
210
226
|
databaseSettings: databaseSettingsInfoSchema,
|
|
@@ -220,6 +236,7 @@ const configInfoSchema = z.object({
|
|
|
220
236
|
multiTenancy: multiTenancySchema.optional().default({}),
|
|
221
237
|
serverExtensions: z.array(serverExtensionSchema).optional().default([]),
|
|
222
238
|
cacheSettings: cacheSettingsSchema.optional().default({}),
|
|
239
|
+
feedbackSettings: feedbackSettingsSchema.optional().default({}),
|
|
223
240
|
|
|
224
241
|
apiKey: z.string().optional(),
|
|
225
242
|
baseUrl: z.string().default('http://localhost'),
|
|
@@ -267,6 +284,8 @@ export type QueryDialectConfig = z.infer<typeof queryDialectSchema>;
|
|
|
267
284
|
export type MultiTenancyConfig = z.infer<typeof multiTenancySchema>;
|
|
268
285
|
export type ServerExtensionConfig = z.infer<typeof serverExtensionSchema>;
|
|
269
286
|
export type CacheSettingsConfig = z.infer<typeof cacheSettingsSchema>;
|
|
287
|
+
export type FeedbackGithubSettingsConfig = z.infer<typeof feedbackGithubSettingsSchema>;
|
|
288
|
+
export type FeedbackSettingsConfig = z.infer<typeof feedbackSettingsSchema>;
|
|
270
289
|
export type ConfigInfo = z.infer<typeof configInfoSchema>;
|
|
271
290
|
|
|
272
291
|
/**
|