@memberjunction/server 2.12.0 → 2.13.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/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +4 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/newUsers.d.ts +1 -1
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +49 -35
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/generated/generated.d.ts +59 -59
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +344 -344
- package/dist/generated/generated.js.map +1 -1
- package/package.json +22 -22
- package/src/auth/index.ts +14 -5
- package/src/auth/newUsers.ts +61 -37
- package/src/generated/generated.ts +218 -218
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.1",
|
|
4
4
|
"description": "MemberJunction: This project provides API access via GraphQL to the common data store.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -22,27 +22,27 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@apollo/server": "^4.9.1",
|
|
24
24
|
"@graphql-tools/utils": "^10.0.1",
|
|
25
|
-
"@memberjunction/actions": "2.
|
|
26
|
-
"@memberjunction/ai": "2.
|
|
27
|
-
"@memberjunction/ai-mistral": "2.
|
|
28
|
-
"@memberjunction/ai-openai": "2.
|
|
29
|
-
"@memberjunction/ai-vectors-pinecone": "2.
|
|
30
|
-
"@memberjunction/aiengine": "2.
|
|
31
|
-
"@memberjunction/core": "2.
|
|
32
|
-
"@memberjunction/core-actions": "2.
|
|
33
|
-
"@memberjunction/core-entities": "2.
|
|
34
|
-
"@memberjunction/data-context": "2.
|
|
35
|
-
"@memberjunction/data-context-server": "2.
|
|
36
|
-
"@memberjunction/doc-utils": "2.
|
|
37
|
-
"@memberjunction/entity-communications-server": "2.
|
|
38
|
-
"@memberjunction/external-change-detection": "2.
|
|
39
|
-
"@memberjunction/global": "2.
|
|
40
|
-
"@memberjunction/queue": "2.
|
|
41
|
-
"@memberjunction/skip-types": "2.
|
|
42
|
-
"@memberjunction/sqlserver-dataprovider": "2.
|
|
43
|
-
"@memberjunction/graphql-dataprovider": "2.
|
|
44
|
-
"@memberjunction/storage": "2.
|
|
45
|
-
"@memberjunction/templates": "2.
|
|
25
|
+
"@memberjunction/actions": "2.13.1",
|
|
26
|
+
"@memberjunction/ai": "2.13.1",
|
|
27
|
+
"@memberjunction/ai-mistral": "2.13.1",
|
|
28
|
+
"@memberjunction/ai-openai": "2.13.1",
|
|
29
|
+
"@memberjunction/ai-vectors-pinecone": "2.13.1",
|
|
30
|
+
"@memberjunction/aiengine": "2.13.1",
|
|
31
|
+
"@memberjunction/core": "2.13.1",
|
|
32
|
+
"@memberjunction/core-actions": "2.13.1",
|
|
33
|
+
"@memberjunction/core-entities": "2.13.1",
|
|
34
|
+
"@memberjunction/data-context": "2.13.1",
|
|
35
|
+
"@memberjunction/data-context-server": "2.13.1",
|
|
36
|
+
"@memberjunction/doc-utils": "2.13.1",
|
|
37
|
+
"@memberjunction/entity-communications-server": "2.13.1",
|
|
38
|
+
"@memberjunction/external-change-detection": "2.13.1",
|
|
39
|
+
"@memberjunction/global": "2.13.1",
|
|
40
|
+
"@memberjunction/queue": "2.13.1",
|
|
41
|
+
"@memberjunction/skip-types": "2.13.1",
|
|
42
|
+
"@memberjunction/sqlserver-dataprovider": "2.13.1",
|
|
43
|
+
"@memberjunction/graphql-dataprovider": "2.13.1",
|
|
44
|
+
"@memberjunction/storage": "2.13.1",
|
|
45
|
+
"@memberjunction/templates": "2.13.1",
|
|
46
46
|
"@types/cors": "^2.8.13",
|
|
47
47
|
"@types/jsonwebtoken": "9.0.6",
|
|
48
48
|
"@types/node": "20.14.2",
|
package/src/auth/index.ts
CHANGED
|
@@ -3,9 +3,10 @@ import jwksClient from 'jwks-rsa';
|
|
|
3
3
|
import { auth0Domain, auth0WebClientID, configInfo, tenantID, webClientID } from '../config.js';
|
|
4
4
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
5
5
|
import { DataSource } from 'typeorm';
|
|
6
|
-
import { Metadata, UserInfo } from '@memberjunction/core';
|
|
6
|
+
import { Metadata, RoleInfo, UserInfo } from '@memberjunction/core';
|
|
7
7
|
import { NewUserBase } from './newUsers.js';
|
|
8
8
|
import { MJGlobal } from '@memberjunction/global';
|
|
9
|
+
import { UserEntity, UserEntityType } from '@memberjunction/core-entities';
|
|
9
10
|
|
|
10
11
|
export { TokenExpiredError } from './tokenExpiredError.js';
|
|
11
12
|
|
|
@@ -120,15 +121,22 @@ export const verifyUserRecord = async (
|
|
|
120
121
|
if (passesDomainCheck) {
|
|
121
122
|
// we have a domain from the request that matches one of the domains provided by the configuration, so we will create a new user
|
|
122
123
|
console.warn(`User ${email} not found in cache. Attempting to create a new user...`);
|
|
123
|
-
const newUserCreator: NewUserBase =
|
|
124
|
-
const newUser = await newUserCreator.createNewUser(firstName, lastName, email);
|
|
124
|
+
const newUserCreator: NewUserBase = MJGlobal.Instance.ClassFactory.CreateInstance<NewUserBase>(NewUserBase); // this will create the object that handles creating the new user for us
|
|
125
|
+
const newUser: UserEntity | null = await newUserCreator.createNewUser(firstName, lastName, email);
|
|
125
126
|
if (newUser) {
|
|
126
127
|
// new user worked! we already have the stuff we need for the cache, so no need to go to the DB now, just create a new UserInfo object and use the return value from the createNewUser method
|
|
127
128
|
// to init it, including passing in the role list for the user.
|
|
128
|
-
const
|
|
129
|
+
const md: Metadata = new Metadata();
|
|
130
|
+
|
|
131
|
+
const initData: UserEntityType & {UserRoles: {UserID: string, RoleName: string, RoleID: string}[] } = newUser.GetAll();
|
|
132
|
+
|
|
129
133
|
initData.UserRoles = configInfo.userHandling.newUserRoles.map((role) => {
|
|
130
|
-
|
|
134
|
+
const roleInfo: RoleInfo | undefined = md.Roles.find((r) => r.Name === role);
|
|
135
|
+
const roleID: string = roleInfo ? roleInfo.ID : "";
|
|
136
|
+
|
|
137
|
+
return { UserID: initData.ID, RoleName: role, RoleID: roleID };
|
|
131
138
|
});
|
|
139
|
+
|
|
132
140
|
user = new UserInfo(Metadata.Provider, initData);
|
|
133
141
|
UserCache.Instance.Users.push(user);
|
|
134
142
|
console.warn(` >>> New user ${email} created successfully!`);
|
|
@@ -139,6 +147,7 @@ export const verifyUserRecord = async (
|
|
|
139
147
|
);
|
|
140
148
|
}
|
|
141
149
|
}
|
|
150
|
+
|
|
142
151
|
if (!user && configInfo.userHandling.updateCacheWhenNotFound && dataSource && attemptCacheUpdateIfNeeded) {
|
|
143
152
|
// if we get here that means in the above, if we were attempting to create a new user, it did not work, or it wasn't attempted and we have a config that asks us to auto update the cache
|
|
144
153
|
console.warn(`User ${email} not found in cache. Updating cache in attempt to find the user...`);
|
package/src/auth/newUsers.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LogError, Metadata } from "@memberjunction/core";
|
|
1
|
+
import { LogError, LogStatus, Metadata, 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";
|
|
@@ -6,49 +6,73 @@ import { UserEntity, UserRoleEntity } from "@memberjunction/core-entities";
|
|
|
6
6
|
|
|
7
7
|
@RegisterClass(NewUserBase)
|
|
8
8
|
export class NewUserBase {
|
|
9
|
-
public async createNewUser(firstName: string, lastName: string, email: string, linkedRecordType: string = 'None', linkedEntityId?: string, linkedEntityRecordId?: string) {
|
|
9
|
+
public async createNewUser(firstName: string, lastName: string, email: string, linkedRecordType: string = 'None', linkedEntityId?: string, linkedEntityRecordId?: string): Promise<UserEntity | null> {
|
|
10
10
|
try {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
let contextUser: UserInfo | null = null;
|
|
12
|
+
|
|
13
|
+
const contextUserForNewUserCreation: string = configInfo?.userHandling?.contextUserForNewUserCreation;
|
|
14
|
+
if(contextUserForNewUserCreation){
|
|
15
|
+
contextUser = UserCache.Instance.UserByName(contextUserForNewUserCreation);
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
if (!contextUser) {
|
|
14
|
-
LogError(`Failed to load context user ${configInfo?.userHandling?.contextUserForNewUserCreation},
|
|
15
|
-
|
|
19
|
+
LogError(`Failed to load context user ${configInfo?.userHandling?.contextUserForNewUserCreation}, using an existing user with the Owner role instead`);
|
|
20
|
+
|
|
21
|
+
contextUser = UserCache.Users.find(user => user.Type.trim().toLowerCase() ==='owner')!;
|
|
22
|
+
if (!contextUser) {
|
|
23
|
+
LogError(`No existing users found in the database with the Owner role, cannot create a new user`);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const md: Metadata = new Metadata();
|
|
29
|
+
const user = await md.GetEntityObject<UserEntity>('Users', contextUser) // To-Do - change this to be a different defined user for the user creation process
|
|
30
|
+
user.NewRecord();
|
|
31
|
+
user.Name = email;
|
|
32
|
+
user.IsActive = true;
|
|
33
|
+
user.FirstName = firstName;
|
|
34
|
+
user.LastName = lastName;
|
|
35
|
+
user.Email = email;
|
|
36
|
+
user.Type = 'User';
|
|
37
|
+
user.LinkedRecordType = linkedRecordType;
|
|
38
|
+
|
|
39
|
+
if (linkedEntityId){
|
|
40
|
+
user.LinkedEntityID = linkedEntityId;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (linkedEntityRecordId){
|
|
44
|
+
user.LinkedEntityRecordID = linkedEntityRecordId;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const saveResult: boolean = await user.Save();
|
|
48
|
+
if(!saveResult){
|
|
49
|
+
LogError(`Failed to create new user ${firstName} ${lastName} ${email}:`, undefined, user.LatestResult);
|
|
50
|
+
return null;
|
|
16
51
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
u.Name = email;
|
|
20
|
-
u.IsActive = true;
|
|
21
|
-
u.FirstName = firstName;
|
|
22
|
-
u.LastName = lastName;
|
|
23
|
-
u.Email = email;
|
|
24
|
-
u.Type = 'User';
|
|
25
|
-
u.LinkedRecordType = linkedRecordType;
|
|
26
|
-
if (linkedEntityId)
|
|
27
|
-
u.LinkedEntityID = linkedEntityId;
|
|
28
|
-
if (linkedEntityRecordId)
|
|
29
|
-
u.LinkedEntityRecordID = linkedEntityRecordId;
|
|
30
|
-
|
|
31
|
-
if (await u.Save()) {
|
|
52
|
+
|
|
53
|
+
if(configInfo.userHandling && configInfo.userHandling.newUserRoles){
|
|
32
54
|
// user created, now create however many roles we need to create for this user based on the config settings
|
|
33
|
-
|
|
34
|
-
let bSuccess: boolean = true;
|
|
55
|
+
LogStatus(`User ${user.Email} created, assigning roles`);
|
|
35
56
|
for (const role of configInfo.userHandling.newUserRoles) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
const userRoleEntity: UserRoleEntity = await md.GetEntityObject<UserRoleEntity>('User Roles', contextUser);
|
|
58
|
+
userRoleEntity.NewRecord();
|
|
59
|
+
userRoleEntity.UserID = user.ID;
|
|
60
|
+
const userRole = md.Roles.find(r => r.Name === role);
|
|
61
|
+
|
|
62
|
+
if (!userRole) {
|
|
63
|
+
LogError(`Role ${role} not found in the database, cannot assign to new user ${user.Name}`);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
userRoleEntity.RoleID = userRole.ID;
|
|
68
|
+
const roleSaveResult: boolean = await userRoleEntity.Save();
|
|
69
|
+
if(!roleSaveResult){
|
|
70
|
+
LogError(`Failed to assign role ${role} to new user ${user.Name}:`, undefined, userRoleEntity.LatestResult);
|
|
71
|
+
}
|
|
45
72
|
}
|
|
46
73
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return undefined;
|
|
50
|
-
}
|
|
51
|
-
return u;
|
|
74
|
+
|
|
75
|
+
return user;
|
|
52
76
|
}
|
|
53
77
|
catch (e) {
|
|
54
78
|
LogError(e);
|