@memberjunction/server 3.3.0 → 4.0.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/README.md +59 -0
- package/dist/agents/skip-agent.d.ts +65 -0
- package/dist/agents/skip-agent.d.ts.map +1 -1
- package/dist/agents/skip-agent.js +63 -5
- package/dist/agents/skip-agent.js.map +1 -1
- package/dist/agents/skip-sdk.d.ts +163 -0
- package/dist/agents/skip-sdk.d.ts.map +1 -1
- package/dist/agents/skip-sdk.js +143 -12
- package/dist/agents/skip-sdk.js.map +1 -1
- package/dist/apolloServer/TransactionPlugin.d.ts +4 -0
- package/dist/apolloServer/TransactionPlugin.d.ts.map +1 -0
- package/dist/apolloServer/TransactionPlugin.js +46 -0
- package/dist/apolloServer/TransactionPlugin.js.map +1 -0
- package/dist/apolloServer/index.d.ts +0 -1
- package/dist/apolloServer/index.d.ts.map +1 -1
- package/dist/auth/APIKeyScopeAuth.d.ts +82 -0
- package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
- package/dist/auth/APIKeyScopeAuth.js +78 -0
- package/dist/auth/APIKeyScopeAuth.js.map +1 -1
- package/dist/auth/AuthProviderFactory.d.ts +35 -0
- package/dist/auth/AuthProviderFactory.d.ts.map +1 -1
- package/dist/auth/AuthProviderFactory.js +51 -4
- package/dist/auth/AuthProviderFactory.js.map +1 -1
- package/dist/auth/BaseAuthProvider.d.ts +22 -0
- package/dist/auth/BaseAuthProvider.d.ts.map +1 -1
- package/dist/auth/BaseAuthProvider.js +25 -8
- package/dist/auth/BaseAuthProvider.js.map +1 -1
- package/dist/auth/IAuthProvider.d.ts +33 -0
- package/dist/auth/IAuthProvider.d.ts.map +1 -1
- package/dist/auth/__tests__/backward-compatibility.test.d.ts +2 -0
- package/dist/auth/__tests__/backward-compatibility.test.d.ts.map +1 -0
- package/dist/auth/__tests__/backward-compatibility.test.js +135 -0
- package/dist/auth/__tests__/backward-compatibility.test.js.map +1 -0
- package/dist/auth/exampleNewUserSubClass.d.ts +5 -1
- package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
- package/dist/auth/exampleNewUserSubClass.js +21 -6
- package/dist/auth/exampleNewUserSubClass.js.map +1 -1
- package/dist/auth/index.d.ts +14 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +35 -22
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/initializeProviders.d.ts +3 -0
- package/dist/auth/initializeProviders.d.ts.map +1 -1
- package/dist/auth/initializeProviders.js +6 -0
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/auth/newUsers.js +11 -2
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/auth/providers/Auth0Provider.d.ts +9 -0
- package/dist/auth/providers/Auth0Provider.d.ts.map +1 -1
- package/dist/auth/providers/Auth0Provider.js +10 -0
- package/dist/auth/providers/Auth0Provider.js.map +1 -1
- package/dist/auth/providers/CognitoProvider.d.ts +9 -0
- package/dist/auth/providers/CognitoProvider.d.ts.map +1 -1
- package/dist/auth/providers/CognitoProvider.js +10 -0
- package/dist/auth/providers/CognitoProvider.js.map +1 -1
- package/dist/auth/providers/GoogleProvider.d.ts +9 -0
- package/dist/auth/providers/GoogleProvider.d.ts.map +1 -1
- package/dist/auth/providers/GoogleProvider.js +11 -1
- package/dist/auth/providers/GoogleProvider.js.map +1 -1
- package/dist/auth/providers/MSALProvider.d.ts +9 -0
- package/dist/auth/providers/MSALProvider.d.ts.map +1 -1
- package/dist/auth/providers/MSALProvider.js +10 -0
- package/dist/auth/providers/MSALProvider.js.map +1 -1
- package/dist/auth/providers/OktaProvider.d.ts +9 -0
- package/dist/auth/providers/OktaProvider.d.ts.map +1 -1
- package/dist/auth/providers/OktaProvider.js +10 -0
- package/dist/auth/providers/OktaProvider.js.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +44 -10
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +8 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +26 -4
- package/dist/context.js.map +1 -1
- package/dist/directives/Public.js +2 -0
- package/dist/directives/Public.js.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.d.ts +7 -2
- package/dist/entitySubclasses/entityPermissions.server.d.ts.map +1 -1
- package/dist/entitySubclasses/entityPermissions.server.js +26 -8
- package/dist/entitySubclasses/entityPermissions.server.js.map +1 -1
- package/dist/generated/generated.d.ts +954 -2
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +12183 -14532
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/DeleteOptionsInput.d.ts +3 -0
- package/dist/generic/DeleteOptionsInput.d.ts.map +1 -1
- package/dist/generic/DeleteOptionsInput.js +3 -2
- package/dist/generic/DeleteOptionsInput.js.map +1 -1
- package/dist/generic/KeyInputOutputTypes.js +0 -6
- package/dist/generic/KeyInputOutputTypes.js.map +1 -1
- package/dist/generic/KeyValuePairInput.d.ts +4 -0
- package/dist/generic/KeyValuePairInput.d.ts.map +1 -1
- package/dist/generic/KeyValuePairInput.js +4 -2
- package/dist/generic/KeyValuePairInput.js.map +1 -1
- package/dist/generic/PushStatusResolver.js +0 -3
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +59 -0
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +233 -18
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +22 -0
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +42 -108
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -39
- package/dist/index.js.map +1 -1
- package/dist/orm.d.ts.map +1 -1
- package/dist/orm.js +2 -1
- package/dist/orm.js.map +1 -1
- package/dist/resolvers/APIKeyResolver.d.ts +76 -1
- package/dist/resolvers/APIKeyResolver.d.ts.map +1 -1
- package/dist/resolvers/APIKeyResolver.js +53 -11
- package/dist/resolvers/APIKeyResolver.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts +191 -1
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +156 -22
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/ColorResolver.js +0 -5
- package/dist/resolvers/ColorResolver.js.map +1 -1
- package/dist/resolvers/ComponentRegistryResolver.d.ts +65 -0
- package/dist/resolvers/ComponentRegistryResolver.d.ts.map +1 -1
- package/dist/resolvers/ComponentRegistryResolver.js +118 -40
- package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
- package/dist/resolvers/CreateQueryResolver.d.ts +47 -0
- package/dist/resolvers/CreateQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/CreateQueryResolver.js +92 -116
- package/dist/resolvers/CreateQueryResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts +5 -4
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +9 -18
- package/dist/resolvers/DatasetResolver.js.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts +42 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.js +5 -37
- package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +0 -7
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +13 -1
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +16 -0
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +59 -74
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts +20 -2
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +27 -12
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts +19 -0
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +35 -35
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/InfoResolver.d.ts.map +1 -1
- package/dist/resolvers/InfoResolver.js +4 -7
- package/dist/resolvers/InfoResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts +361 -0
- package/dist/resolvers/MCPResolver.d.ts.map +1 -0
- package/dist/resolvers/MCPResolver.js +1270 -0
- package/dist/resolvers/MCPResolver.js.map +1 -0
- package/dist/resolvers/MergeRecordsResolver.d.ts +2 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +6 -30
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.d.ts.map +1 -1
- package/dist/resolvers/PotentialDuplicateRecordResolver.js +0 -3
- package/dist/resolvers/PotentialDuplicateRecordResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts +22 -1
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +50 -37
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/ReportResolver.d.ts +5 -1
- package/dist/resolvers/ReportResolver.d.ts.map +1 -1
- package/dist/resolvers/ReportResolver.js +13 -11
- package/dist/resolvers/ReportResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +54 -0
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +118 -40
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +42 -0
- package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +98 -22
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +10 -6
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/RunTestResolver.d.ts +12 -0
- package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTestResolver.js +35 -21
- package/dist/resolvers/RunTestResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts +312 -0
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +295 -45
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts +21 -0
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +36 -22
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +14 -0
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +54 -21
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/TaskResolver.d.ts +13 -0
- package/dist/resolvers/TaskResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskResolver.js +23 -7
- package/dist/resolvers/TaskResolver.js.map +1 -1
- package/dist/resolvers/TelemetryResolver.d.ts +22 -0
- package/dist/resolvers/TelemetryResolver.d.ts.map +1 -1
- package/dist/resolvers/TelemetryResolver.js +45 -79
- package/dist/resolvers/TelemetryResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +11 -13
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/UserFavoriteResolver.js +3 -12
- package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
- package/dist/resolvers/UserResolver.d.ts.map +1 -1
- package/dist/resolvers/UserResolver.js +14 -0
- package/dist/resolvers/UserResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.js +4 -0
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/resolvers/VersionHistoryResolver.d.ts +39 -0
- package/dist/resolvers/VersionHistoryResolver.d.ts.map +1 -0
- package/dist/resolvers/VersionHistoryResolver.js +208 -0
- package/dist/resolvers/VersionHistoryResolver.js.map +1 -0
- package/dist/rest/EntityCRUDHandler.d.ts +19 -0
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +55 -0
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.d.ts +143 -0
- package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -0
- package/dist/rest/OAuthCallbackHandler.js +634 -0
- package/dist/rest/OAuthCallbackHandler.js.map +1 -0
- package/dist/rest/RESTEndpointHandler.d.ts +120 -0
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +213 -24
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts +19 -0
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +39 -0
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/index.d.ts +1 -0
- package/dist/rest/index.d.ts.map +1 -1
- package/dist/rest/index.js +1 -0
- package/dist/rest/index.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +35 -0
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +15 -1
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/services/ScheduledJobsService.d.ts +31 -0
- package/dist/services/ScheduledJobsService.d.ts.map +1 -1
- package/dist/services/ScheduledJobsService.js +38 -4
- package/dist/services/ScheduledJobsService.js.map +1 -1
- package/dist/services/TaskOrchestrator.d.ts +73 -0
- package/dist/services/TaskOrchestrator.d.ts.map +1 -1
- package/dist/services/TaskOrchestrator.js +137 -15
- package/dist/services/TaskOrchestrator.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -13
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +37 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +55 -8
- package/dist/util.js.map +1 -1
- package/package.json +79 -77
- package/src/auth/BaseAuthProvider.ts +3 -0
- package/src/auth/IAuthProvider.ts +5 -0
- package/src/auth/exampleNewUserSubClass.ts +1 -5
- package/src/config.ts +2 -2
- package/src/entitySubclasses/entityPermissions.server.ts +1 -3
- package/src/generated/generated.ts +6245 -2558
- package/src/generic/ResolverBase.ts +89 -3
- package/src/index.ts +71 -64
- package/src/resolvers/APIKeyResolver.ts +8 -1
- package/src/resolvers/ActionResolver.ts +8 -1
- package/src/resolvers/DatasetResolver.ts +11 -4
- package/src/resolvers/EntityCommunicationsResolver.ts +5 -1
- package/src/resolvers/GetDataContextDataResolver.ts +14 -6
- package/src/resolvers/InfoResolver.ts +5 -1
- package/src/resolvers/MCPResolver.ts +1380 -0
- package/src/resolvers/MergeRecordsResolver.ts +5 -1
- package/src/resolvers/PotentialDuplicateRecordResolver.ts +0 -4
- package/src/resolvers/QueryResolver.ts +17 -3
- package/src/resolvers/ReportResolver.ts +8 -1
- package/src/resolvers/RunAIAgentResolver.ts +6 -0
- package/src/resolvers/RunAIPromptResolver.ts +10 -1
- package/src/resolvers/RunTemplateResolver.ts +4 -1
- package/src/resolvers/TaskResolver.ts +3 -0
- package/src/resolvers/UserResolver.ts +15 -3
- package/src/resolvers/VersionHistoryResolver.ts +177 -0
- package/src/rest/OAuthCallbackHandler.ts +766 -0
- package/src/rest/RESTEndpointHandler.ts +58 -35
- package/src/rest/index.ts +2 -1
- package/src/rest/setupRESTEndpoints.ts +13 -12
- package/src/resolvers/AskSkipResolver.ts +0 -3446
- package/src/scheduler/LearningCycleScheduler.ts +0 -320
|
@@ -1,23 +1,38 @@
|
|
|
1
1
|
import { BaseAuthProvider } from './BaseAuthProvider.js';
|
|
2
2
|
import { MJGlobal } from '@memberjunction/global';
|
|
3
|
+
// Import providers to ensure they're registered
|
|
3
4
|
import './providers/Auth0Provider.js';
|
|
4
5
|
import './providers/MSALProvider.js';
|
|
5
6
|
import './providers/OktaProvider.js';
|
|
6
7
|
import './providers/CognitoProvider.js';
|
|
7
8
|
import './providers/GoogleProvider.js';
|
|
9
|
+
/**
|
|
10
|
+
* Factory and registry for managing authentication providers
|
|
11
|
+
* Combines provider creation and lifecycle management in a single class
|
|
12
|
+
*/
|
|
8
13
|
export class AuthProviderFactory {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
constructor() {
|
|
15
|
+
this.providers = new Map();
|
|
16
|
+
this.issuerCache = new Map();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Gets the singleton instance of the factory
|
|
20
|
+
*/
|
|
13
21
|
static getInstance() {
|
|
14
22
|
if (!AuthProviderFactory.instance) {
|
|
15
23
|
AuthProviderFactory.instance = new AuthProviderFactory();
|
|
16
24
|
}
|
|
17
25
|
return AuthProviderFactory.instance;
|
|
18
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates an authentication provider instance based on configuration
|
|
29
|
+
* Uses MJGlobal ClassFactory to instantiate the correct provider class
|
|
30
|
+
*/
|
|
19
31
|
static createProvider(config) {
|
|
20
32
|
try {
|
|
33
|
+
// Use MJGlobal ClassFactory to create the provider instance
|
|
34
|
+
// The provider type in config should match the key used in @RegisterClass
|
|
35
|
+
// The config is passed as a constructor parameter via the spread operator
|
|
21
36
|
const provider = MJGlobal.Instance.ClassFactory.CreateInstance(BaseAuthProvider, config.type.toLowerCase(), config);
|
|
22
37
|
if (!provider) {
|
|
23
38
|
throw new Error(`No provider registered for type: ${config.type}`);
|
|
@@ -29,48 +44,80 @@ export class AuthProviderFactory {
|
|
|
29
44
|
throw new Error(`Failed to create authentication provider for type '${config.type}': ${message}`);
|
|
30
45
|
}
|
|
31
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Registers a new authentication provider
|
|
49
|
+
*/
|
|
32
50
|
register(provider) {
|
|
33
51
|
if (!provider.validateConfig()) {
|
|
34
52
|
throw new Error(`Invalid configuration for provider: ${provider.name}`);
|
|
35
53
|
}
|
|
36
54
|
this.providers.set(provider.name, provider);
|
|
55
|
+
// Clear issuer cache when registering new provider
|
|
37
56
|
this.issuerCache.clear();
|
|
38
57
|
console.log(`Registered auth provider: ${provider.name} with issuer: ${provider.issuer}`);
|
|
39
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Gets a provider by its issuer URL
|
|
61
|
+
*/
|
|
40
62
|
getByIssuer(issuer) {
|
|
63
|
+
// Check cache first
|
|
41
64
|
if (this.issuerCache.has(issuer)) {
|
|
42
65
|
return this.issuerCache.get(issuer);
|
|
43
66
|
}
|
|
67
|
+
// Search through providers
|
|
44
68
|
for (const provider of this.providers.values()) {
|
|
45
69
|
if (provider.matchesIssuer(issuer)) {
|
|
70
|
+
// Cache for future lookups
|
|
46
71
|
this.issuerCache.set(issuer, provider);
|
|
47
72
|
return provider;
|
|
48
73
|
}
|
|
49
74
|
}
|
|
50
75
|
return undefined;
|
|
51
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Gets a provider by its name
|
|
79
|
+
*/
|
|
52
80
|
getByName(name) {
|
|
53
81
|
return this.providers.get(name);
|
|
54
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Gets all registered providers
|
|
85
|
+
*/
|
|
55
86
|
getAllProviders() {
|
|
56
87
|
return Array.from(this.providers.values());
|
|
57
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Checks if any providers are registered
|
|
91
|
+
*/
|
|
58
92
|
hasProviders() {
|
|
59
93
|
return this.providers.size > 0;
|
|
60
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Clears all registered providers (useful for testing)
|
|
97
|
+
*/
|
|
61
98
|
clear() {
|
|
62
99
|
this.providers.clear();
|
|
63
100
|
this.issuerCache.clear();
|
|
64
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Gets all registered provider types from the ClassFactory
|
|
104
|
+
*/
|
|
65
105
|
static getRegisteredProviderTypes() {
|
|
106
|
+
// Get all registrations for BaseAuthProvider from ClassFactory
|
|
66
107
|
const registrations = MJGlobal.Instance.ClassFactory.GetAllRegistrations(BaseAuthProvider);
|
|
108
|
+
// Extract unique keys (provider types) from registrations
|
|
67
109
|
const providerTypes = registrations
|
|
68
110
|
.map(reg => reg.Key)
|
|
69
111
|
.filter((key) => key !== null && key !== undefined);
|
|
112
|
+
// Return unique provider types
|
|
70
113
|
return Array.from(new Set(providerTypes));
|
|
71
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Checks if a provider type is registered
|
|
117
|
+
*/
|
|
72
118
|
static isProviderTypeRegistered(type) {
|
|
73
119
|
try {
|
|
120
|
+
// Try to get the registration for this specific type
|
|
74
121
|
const registration = MJGlobal.Instance.ClassFactory.GetRegistration(BaseAuthProvider, type.toLowerCase());
|
|
75
122
|
return registration !== null && registration !== undefined;
|
|
76
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProviderFactory.js","sourceRoot":"","sources":["../../src/auth/AuthProviderFactory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthProviderFactory.js","sourceRoot":"","sources":["../../src/auth/AuthProviderFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,18 +2,40 @@ import { JwtHeader, JwtPayload, SigningKeyCallback } from 'jsonwebtoken';
|
|
|
2
2
|
import jwksClient from 'jwks-rsa';
|
|
3
3
|
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
4
4
|
import { IAuthProvider } from './IAuthProvider.js';
|
|
5
|
+
/**
|
|
6
|
+
* Base implementation of IAuthProvider with common functionality
|
|
7
|
+
* Concrete providers should extend this class and use @RegisterClass decorator
|
|
8
|
+
* with BaseAuthProvider as the base class
|
|
9
|
+
*/
|
|
5
10
|
export declare abstract class BaseAuthProvider implements IAuthProvider {
|
|
6
11
|
name: string;
|
|
7
12
|
issuer: string;
|
|
8
13
|
audience: string;
|
|
9
14
|
jwksUri: string;
|
|
15
|
+
/** OAuth client ID for this provider (used by OAuth proxy for upstream auth) */
|
|
16
|
+
clientId?: string;
|
|
10
17
|
protected config: AuthProviderConfig;
|
|
11
18
|
protected jwksClient: jwksClient.JwksClient;
|
|
12
19
|
constructor(config: AuthProviderConfig);
|
|
20
|
+
/**
|
|
21
|
+
* Validates that required configuration is present
|
|
22
|
+
*/
|
|
13
23
|
validateConfig(): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Gets the signing key for token verification with retry logic
|
|
26
|
+
*/
|
|
14
27
|
getSigningKey(header: JwtHeader, callback: SigningKeyCallback): void;
|
|
28
|
+
/**
|
|
29
|
+
* Retrieves signing key with exponential backoff retry logic
|
|
30
|
+
*/
|
|
15
31
|
private getSigningKeyWithRetry;
|
|
32
|
+
/**
|
|
33
|
+
* Checks if a given issuer URL belongs to this provider
|
|
34
|
+
*/
|
|
16
35
|
matchesIssuer(issuer: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Abstract method for extracting user info - must be implemented by each provider
|
|
38
|
+
*/
|
|
17
39
|
abstract extractUserInfo(payload: JwtPayload): AuthUserInfo;
|
|
18
40
|
}
|
|
19
41
|
//# sourceMappingURL=BaseAuthProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseAuthProvider.d.ts","sourceRoot":"","sources":["../../src/auth/BaseAuthProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,UAAU,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseAuthProvider.d.ts","sourceRoot":"","sources":["../../src/auth/BaseAuthProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,UAAU,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD;;;;GAIG;AACH,8BAAsB,gBAAiB,YAAW,aAAa;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACrC,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC;gBAEhC,MAAM,EAAE,kBAAkB;IAoCtC;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAYpE;;OAEG;YACW,sBAAsB;IAuCpC;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAOtC;;OAEG;IACH,QAAQ,CAAC,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,YAAY;CAC5D"}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import jwksClient from 'jwks-rsa';
|
|
2
2
|
import https from 'https';
|
|
3
3
|
import http from 'http';
|
|
4
|
+
/**
|
|
5
|
+
* Base implementation of IAuthProvider with common functionality
|
|
6
|
+
* Concrete providers should extend this class and use @RegisterClass decorator
|
|
7
|
+
* with BaseAuthProvider as the base class
|
|
8
|
+
*/
|
|
4
9
|
export class BaseAuthProvider {
|
|
5
|
-
name;
|
|
6
|
-
issuer;
|
|
7
|
-
audience;
|
|
8
|
-
jwksUri;
|
|
9
|
-
config;
|
|
10
|
-
jwksClient;
|
|
11
10
|
constructor(config) {
|
|
12
11
|
this.config = config;
|
|
13
12
|
this.name = config.name;
|
|
14
13
|
this.issuer = config.issuer;
|
|
15
14
|
this.audience = config.audience;
|
|
16
15
|
this.jwksUri = config.jwksUri;
|
|
16
|
+
this.clientId = config.clientId;
|
|
17
|
+
// Create HTTP agent with keep-alive to prevent socket hangups
|
|
17
18
|
const agent = this.jwksUri.startsWith('https')
|
|
18
19
|
? new https.Agent({
|
|
19
20
|
keepAlive: true,
|
|
@@ -29,18 +30,25 @@ export class BaseAuthProvider {
|
|
|
29
30
|
maxFreeSockets: 10,
|
|
30
31
|
timeout: 60000
|
|
31
32
|
});
|
|
33
|
+
// Initialize JWKS client with connection pooling and extended timeout
|
|
32
34
|
this.jwksClient = jwksClient({
|
|
33
35
|
jwksUri: this.jwksUri,
|
|
34
36
|
cache: true,
|
|
35
37
|
cacheMaxEntries: 5,
|
|
36
|
-
cacheMaxAge: 600000,
|
|
37
|
-
timeout: 60000,
|
|
38
|
+
cacheMaxAge: 600000, // 10 minutes
|
|
39
|
+
timeout: 60000, // 60 seconds (increased from default 30s)
|
|
38
40
|
requestAgent: agent
|
|
39
41
|
});
|
|
40
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Validates that required configuration is present
|
|
45
|
+
*/
|
|
41
46
|
validateConfig() {
|
|
42
47
|
return !!(this.name && this.issuer && this.audience && this.jwksUri);
|
|
43
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Gets the signing key for token verification with retry logic
|
|
51
|
+
*/
|
|
44
52
|
getSigningKey(header, callback) {
|
|
45
53
|
this.getSigningKeyWithRetry(header, 3, 1000)
|
|
46
54
|
.then((key) => {
|
|
@@ -52,6 +60,9 @@ export class BaseAuthProvider {
|
|
|
52
60
|
callback(err);
|
|
53
61
|
});
|
|
54
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Retrieves signing key with exponential backoff retry logic
|
|
65
|
+
*/
|
|
55
66
|
async getSigningKeyWithRetry(header, maxRetries, initialDelayMs) {
|
|
56
67
|
let lastError;
|
|
57
68
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
@@ -60,6 +71,7 @@ export class BaseAuthProvider {
|
|
|
60
71
|
}
|
|
61
72
|
catch (err) {
|
|
62
73
|
lastError = err instanceof Error ? err : new Error(String(err));
|
|
74
|
+
// Check if this is a connection error that's worth retrying
|
|
63
75
|
const isRetryableError = lastError.message.includes('socket hang up') ||
|
|
64
76
|
lastError.message.includes('ECONNRESET') ||
|
|
65
77
|
lastError.message.includes('ETIMEDOUT') ||
|
|
@@ -68,6 +80,7 @@ export class BaseAuthProvider {
|
|
|
68
80
|
if (!isRetryableError || attempt === maxRetries) {
|
|
69
81
|
throw lastError;
|
|
70
82
|
}
|
|
83
|
+
// Exponential backoff: wait longer between each retry
|
|
71
84
|
const delayMs = initialDelayMs * Math.pow(2, attempt);
|
|
72
85
|
console.warn(`Attempt ${attempt + 1}/${maxRetries + 1} failed for provider ${this.name}. ` +
|
|
73
86
|
`Retrying in ${delayMs}ms... Error: ${lastError.message}`);
|
|
@@ -76,7 +89,11 @@ export class BaseAuthProvider {
|
|
|
76
89
|
}
|
|
77
90
|
throw lastError || new Error('Failed to retrieve signing key');
|
|
78
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Checks if a given issuer URL belongs to this provider
|
|
94
|
+
*/
|
|
79
95
|
matchesIssuer(issuer) {
|
|
96
|
+
// Handle trailing slashes and case sensitivity
|
|
80
97
|
const normalizedIssuer = issuer.toLowerCase().replace(/\/$/, '');
|
|
81
98
|
const normalizedProviderIssuer = this.issuer.toLowerCase().replace(/\/$/, '');
|
|
82
99
|
return normalizedIssuer === normalizedProviderIssuer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseAuthProvider.js","sourceRoot":"","sources":["../../src/auth/BaseAuthProvider.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,UAAU,CAAC;AAGlC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseAuthProvider.js","sourceRoot":"","sources":["../../src/auth/BaseAuthProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,46 @@
|
|
|
1
1
|
import { JwtHeader, JwtPayload, SigningKeyCallback } from 'jsonwebtoken';
|
|
2
2
|
import { AuthUserInfo } from '@memberjunction/core';
|
|
3
|
+
/**
|
|
4
|
+
* Interface for authentication providers in MemberJunction
|
|
5
|
+
* Enables support for any OAuth 2.0/OIDC compliant provider
|
|
6
|
+
*/
|
|
3
7
|
export interface IAuthProvider {
|
|
8
|
+
/**
|
|
9
|
+
* Unique name identifier for this provider
|
|
10
|
+
*/
|
|
4
11
|
name: string;
|
|
12
|
+
/**
|
|
13
|
+
* The issuer URL for this provider (must match the 'iss' claim in tokens)
|
|
14
|
+
*/
|
|
5
15
|
issuer: string;
|
|
16
|
+
/**
|
|
17
|
+
* The expected audience for tokens from this provider
|
|
18
|
+
*/
|
|
6
19
|
audience: string;
|
|
20
|
+
/**
|
|
21
|
+
* The JWKS endpoint URL for retrieving signing keys
|
|
22
|
+
*/
|
|
7
23
|
jwksUri: string;
|
|
24
|
+
/**
|
|
25
|
+
* OAuth client ID for this provider (optional, used by OAuth proxy for upstream authentication)
|
|
26
|
+
*/
|
|
27
|
+
clientId?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Validates that the provider configuration is complete and valid
|
|
30
|
+
*/
|
|
8
31
|
validateConfig(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Gets the signing key for token verification
|
|
34
|
+
*/
|
|
9
35
|
getSigningKey(header: JwtHeader, callback: SigningKeyCallback): void;
|
|
36
|
+
/**
|
|
37
|
+
* Extracts user information from the JWT payload
|
|
38
|
+
* Different providers use different claim names
|
|
39
|
+
*/
|
|
10
40
|
extractUserInfo(payload: JwtPayload): AuthUserInfo;
|
|
41
|
+
/**
|
|
42
|
+
* Checks if a given issuer URL belongs to this provider
|
|
43
|
+
*/
|
|
11
44
|
matchesIssuer(issuer: string): boolean;
|
|
12
45
|
}
|
|
13
46
|
//# sourceMappingURL=IAuthProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IAuthProvider.d.ts","sourceRoot":"","sources":["../../src/auth/IAuthProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAsB,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"IAuthProvider.d.ts","sourceRoot":"","sources":["../../src/auth/IAuthProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAsB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAExE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC;IAE1B;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAErE;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,YAAY,CAAC;IAEnD;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backward-compatibility.test.d.ts","sourceRoot":"","sources":["../../../src/auth/__tests__/backward-compatibility.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals';
|
|
2
|
+
import { AuthProviderFactory } from '../AuthProviderFactory.js';
|
|
3
|
+
import { initializeAuthProviders } from '../initializeProviders.js';
|
|
4
|
+
describe('Authentication Provider Backward Compatibility', () => {
|
|
5
|
+
let factory;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
factory = AuthProviderFactory.getInstance();
|
|
8
|
+
factory.clear();
|
|
9
|
+
});
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
factory.clear();
|
|
12
|
+
});
|
|
13
|
+
describe('Legacy Configuration Support', () => {
|
|
14
|
+
it('should create MSAL provider from legacy config', () => {
|
|
15
|
+
process.env.TENANT_ID = 'test-tenant-id';
|
|
16
|
+
process.env.WEB_CLIENT_ID = 'test-client-id';
|
|
17
|
+
initializeAuthProviders();
|
|
18
|
+
const msalProvider = factory.getByName('msal');
|
|
19
|
+
expect(msalProvider).toBeDefined();
|
|
20
|
+
expect(msalProvider?.issuer).toContain('test-tenant-id');
|
|
21
|
+
expect(msalProvider?.audience).toBe('test-client-id');
|
|
22
|
+
});
|
|
23
|
+
it('should create Auth0 provider from legacy config', () => {
|
|
24
|
+
process.env.AUTH0_DOMAIN = 'test.auth0.com';
|
|
25
|
+
process.env.AUTH0_CLIENT_ID = 'auth0-client-id';
|
|
26
|
+
process.env.AUTH0_CLIENT_SECRET = 'auth0-secret';
|
|
27
|
+
initializeAuthProviders();
|
|
28
|
+
const auth0Provider = factory.getByName('auth0');
|
|
29
|
+
expect(auth0Provider).toBeDefined();
|
|
30
|
+
expect(auth0Provider?.issuer).toBe('https://test.auth0.com/');
|
|
31
|
+
expect(auth0Provider?.audience).toBe('auth0-client-id');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('Provider Registry Functionality', () => {
|
|
35
|
+
it('should find providers by issuer with different formats', () => {
|
|
36
|
+
const testProvider = {
|
|
37
|
+
name: 'test',
|
|
38
|
+
issuer: 'https://test.provider.com/oauth2',
|
|
39
|
+
audience: 'test-audience',
|
|
40
|
+
jwksUri: 'https://test.provider.com/.well-known/jwks.json',
|
|
41
|
+
validateConfig: () => true,
|
|
42
|
+
getSigningKey: jest.fn(),
|
|
43
|
+
extractUserInfo: jest.fn(),
|
|
44
|
+
matchesIssuer: (issuer) => {
|
|
45
|
+
const normalized = issuer.toLowerCase().replace(/\/$/, '');
|
|
46
|
+
return normalized === 'https://test.provider.com/oauth2';
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
factory.register(testProvider);
|
|
50
|
+
expect(factory.getByIssuer('https://test.provider.com/oauth2')).toBe(testProvider);
|
|
51
|
+
expect(factory.getByIssuer('https://test.provider.com/oauth2/')).toBe(testProvider);
|
|
52
|
+
expect(factory.getByIssuer('https://TEST.PROVIDER.COM/oauth2')).toBe(testProvider);
|
|
53
|
+
});
|
|
54
|
+
it('should cache issuer lookups for performance', () => {
|
|
55
|
+
const testProvider = {
|
|
56
|
+
name: 'test',
|
|
57
|
+
issuer: 'https://test.provider.com',
|
|
58
|
+
audience: 'test',
|
|
59
|
+
jwksUri: 'https://test.provider.com/jwks',
|
|
60
|
+
validateConfig: () => true,
|
|
61
|
+
getSigningKey: jest.fn(),
|
|
62
|
+
extractUserInfo: jest.fn(),
|
|
63
|
+
matchesIssuer: jest.fn((issuer) => issuer === 'https://test.provider.com')
|
|
64
|
+
};
|
|
65
|
+
factory.register(testProvider);
|
|
66
|
+
factory.getByIssuer('https://test.provider.com');
|
|
67
|
+
expect(testProvider.matchesIssuer).toHaveBeenCalledTimes(1);
|
|
68
|
+
factory.getByIssuer('https://test.provider.com');
|
|
69
|
+
expect(testProvider.matchesIssuer).toHaveBeenCalledTimes(1);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('User Info Extraction', () => {
|
|
73
|
+
it('should extract user info from different token formats', () => {
|
|
74
|
+
const msalPayload = {
|
|
75
|
+
iss: 'https://login.microsoftonline.com/tenant/v2.0',
|
|
76
|
+
email: 'user@example.com',
|
|
77
|
+
given_name: 'John',
|
|
78
|
+
family_name: 'Doe',
|
|
79
|
+
name: 'John Doe',
|
|
80
|
+
preferred_username: 'john.doe@example.com'
|
|
81
|
+
};
|
|
82
|
+
const auth0Payload = {
|
|
83
|
+
iss: 'https://test.auth0.com/',
|
|
84
|
+
email: 'user@example.com',
|
|
85
|
+
given_name: 'Jane',
|
|
86
|
+
family_name: 'Smith',
|
|
87
|
+
name: 'Jane Smith'
|
|
88
|
+
};
|
|
89
|
+
const oktaPayload = {
|
|
90
|
+
iss: 'https://test.okta.com/oauth2/default',
|
|
91
|
+
email: 'user@example.com',
|
|
92
|
+
given_name: 'Bob',
|
|
93
|
+
family_name: 'Johnson',
|
|
94
|
+
name: 'Bob Johnson',
|
|
95
|
+
preferred_username: 'bob.johnson'
|
|
96
|
+
};
|
|
97
|
+
initializeAuthProviders();
|
|
98
|
+
const msalProvider = factory.getByIssuer(msalPayload.iss);
|
|
99
|
+
if (msalProvider) {
|
|
100
|
+
const msalUserInfo = msalProvider.extractUserInfo(msalPayload);
|
|
101
|
+
expect(msalUserInfo.email).toBe('user@example.com');
|
|
102
|
+
expect(msalUserInfo.firstName).toBe('John');
|
|
103
|
+
expect(msalUserInfo.lastName).toBe('Doe');
|
|
104
|
+
}
|
|
105
|
+
const auth0Provider = factory.getByIssuer(auth0Payload.iss);
|
|
106
|
+
if (auth0Provider) {
|
|
107
|
+
const auth0UserInfo = auth0Provider.extractUserInfo(auth0Payload);
|
|
108
|
+
expect(auth0UserInfo.email).toBe('user@example.com');
|
|
109
|
+
expect(auth0UserInfo.firstName).toBe('Jane');
|
|
110
|
+
expect(auth0UserInfo.lastName).toBe('Smith');
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
describe('Error Handling', () => {
|
|
115
|
+
it('should handle missing provider gracefully', () => {
|
|
116
|
+
const unknownIssuer = 'https://unknown.provider.com';
|
|
117
|
+
const provider = factory.getByIssuer(unknownIssuer);
|
|
118
|
+
expect(provider).toBeUndefined();
|
|
119
|
+
});
|
|
120
|
+
it('should validate provider configuration', () => {
|
|
121
|
+
const invalidProvider = {
|
|
122
|
+
name: 'invalid',
|
|
123
|
+
issuer: '',
|
|
124
|
+
audience: 'test',
|
|
125
|
+
jwksUri: 'https://test.com/jwks',
|
|
126
|
+
validateConfig: () => false,
|
|
127
|
+
getSigningKey: jest.fn(),
|
|
128
|
+
extractUserInfo: jest.fn(),
|
|
129
|
+
matchesIssuer: jest.fn()
|
|
130
|
+
};
|
|
131
|
+
expect(() => factory.register(invalidProvider)).toThrow();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
//# sourceMappingURL=backward-compatibility.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backward-compatibility.test.js","sourceRoot":"","sources":["../../../src/auth/__tests__/backward-compatibility.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { NewUserBase } from './newUsers.js';
|
|
2
2
|
import { UserEntity } from '@memberjunction/core-entities';
|
|
3
|
+
/**
|
|
4
|
+
* This example class subclasses the @NewUserBase class and overrides the createNewUser method to create a new person record and then call the base class to create the user record. In this example there is an entity
|
|
5
|
+
* called "Persons" that is mapped to the User table in the core MemberJunction schema. You can sub-class the NewUserBase to do whatever behavior you want and pre-process, post-process or entirely override the base
|
|
6
|
+
* class behavior.
|
|
7
|
+
*/
|
|
3
8
|
export declare class ExampleNewUserSubClass extends NewUserBase {
|
|
4
9
|
createNewUser(firstName: string, lastName: string, email: string, linkedRecordType?: string, linkedEntityId?: string, linkedEntityRecordId?: string): Promise<UserEntity | null>;
|
|
5
10
|
}
|
|
6
|
-
export declare function LoadExampleNewUserSubClass(): void;
|
|
7
11
|
//# sourceMappingURL=exampleNewUserSubClass.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exampleNewUserSubClass.d.ts","sourceRoot":"","sources":["../../src/auth/exampleNewUserSubClass.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"exampleNewUserSubClass.d.ts","sourceRoot":"","sources":["../../src/auth/exampleNewUserSubClass.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D;;;;GAIG;AAIH,qBAAa,sBAAuB,SAAQ,WAAW;IAC/B,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,GAAE,MAAe,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CA4D/M"}
|
|
@@ -2,6 +2,14 @@ import { Metadata, RunView, LogError } from '@memberjunction/core';
|
|
|
2
2
|
import { NewUserBase } from './newUsers.js';
|
|
3
3
|
import { UserCache } from '@memberjunction/sqlserver-dataprovider';
|
|
4
4
|
import { configInfo } from '../config.js';
|
|
5
|
+
/**
|
|
6
|
+
* This example class subclasses the @NewUserBase class and overrides the createNewUser method to create a new person record and then call the base class to create the user record. In this example there is an entity
|
|
7
|
+
* called "Persons" that is mapped to the User table in the core MemberJunction schema. You can sub-class the NewUserBase to do whatever behavior you want and pre-process, post-process or entirely override the base
|
|
8
|
+
* class behavior.
|
|
9
|
+
*/
|
|
10
|
+
// NOTE: This is commented out becuase it is turned off by default. To make this work, you'd have to do a real implementation below, and then uncomment this decorator
|
|
11
|
+
// so that your class is actually used.
|
|
12
|
+
//@RegisterClass(NewUserBase, undefined, 1) /*by putting 1 into the priority setting, MJGlobal ClassFactory will use this instead of the base class as that registration had no priority*/
|
|
5
13
|
export class ExampleNewUserSubClass extends NewUserBase {
|
|
6
14
|
async createNewUser(firstName, lastName, email, linkedRecordType = 'None', linkedEntityId, linkedEntityRecordId) {
|
|
7
15
|
try {
|
|
@@ -11,31 +19,40 @@ export class ExampleNewUserSubClass extends NewUserBase {
|
|
|
11
19
|
LogError(`Failed to load context user ${configInfo?.userHandling?.contextUserForNewUserCreation}, if you've not specified this on your config.json you must do so. This is the user that is contextually used for creating a new user record dynamically.`);
|
|
12
20
|
return undefined;
|
|
13
21
|
}
|
|
14
|
-
const pEntity = md.Entities.find((e) => e.Name === 'Persons');
|
|
22
|
+
const pEntity = md.Entities.find((e) => e.Name === 'Persons'); // look up the entity info for the Persons entity
|
|
15
23
|
if (!pEntity) {
|
|
16
24
|
LogError('Failed to find Persons entity');
|
|
17
25
|
return undefined;
|
|
18
26
|
}
|
|
19
27
|
let personId;
|
|
28
|
+
// this block of code only executes if we have an entity called Persons
|
|
20
29
|
const rv = new RunView();
|
|
21
30
|
const viewResults = await rv.RunView({
|
|
22
31
|
EntityName: 'Persons',
|
|
23
32
|
ExtraFilter: `Email = '${email}'`,
|
|
24
33
|
}, contextUser);
|
|
25
34
|
if (viewResults && viewResults.Success && Array.isArray(viewResults.Results) && viewResults.Results.length > 0) {
|
|
26
|
-
|
|
35
|
+
// we have a match so use it
|
|
36
|
+
const row = viewResults.Results[0]; // we know the rows will have an ID number
|
|
27
37
|
personId = row['ID'];
|
|
28
38
|
}
|
|
29
39
|
if (!personId) {
|
|
40
|
+
// we don't have a match so create a new person record
|
|
30
41
|
const p = await md.GetEntityObject('Persons', contextUser);
|
|
31
|
-
p.NewRecord();
|
|
42
|
+
p.NewRecord(); // assumes we have an entity called Persons that has FirstName/LastName/Email fields
|
|
43
|
+
// this code is commented out because we don't have a strongly typed sub-class generatd for this "Persons" entity as it is a demo/hypothetical example
|
|
44
|
+
//p.FirstName = firstName;
|
|
45
|
+
//p.LastName = lastName;
|
|
46
|
+
//p.Email = email;
|
|
47
|
+
//p.Status = 'active';
|
|
32
48
|
if (await p.Save()) {
|
|
33
|
-
personId = p.FirstPrimaryKey.Value;
|
|
49
|
+
personId = p.FirstPrimaryKey.Value; // if we had a strongly typed sub-class above, we could use this code p.ID;
|
|
34
50
|
}
|
|
35
51
|
else {
|
|
36
52
|
LogError(`Failed to create new person ${firstName} ${lastName} ${email}`);
|
|
37
53
|
}
|
|
38
54
|
}
|
|
55
|
+
// now call the base class to create the user, and pass in our LinkedRecordType and ID
|
|
39
56
|
return super.createNewUser(firstName, lastName, email, 'Other', pEntity?.ID, personId);
|
|
40
57
|
}
|
|
41
58
|
catch (e) {
|
|
@@ -44,6 +61,4 @@ export class ExampleNewUserSubClass extends NewUserBase {
|
|
|
44
61
|
}
|
|
45
62
|
}
|
|
46
63
|
}
|
|
47
|
-
export function LoadExampleNewUserSubClass() {
|
|
48
|
-
}
|
|
49
64
|
//# sourceMappingURL=exampleNewUserSubClass.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exampleNewUserSubClass.js","sourceRoot":"","sources":["../../src/auth/exampleNewUserSubClass.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAqB,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"exampleNewUserSubClass.js","sourceRoot":"","sources":["../../src/auth/exampleNewUserSubClass.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -5,10 +5,18 @@ export { TokenExpiredError } from './tokenExpiredError.js';
|
|
|
5
5
|
export { IAuthProvider } from './IAuthProvider.js';
|
|
6
6
|
export { AuthProviderFactory } from './AuthProviderFactory.js';
|
|
7
7
|
export * from './APIKeyScopeAuth.js';
|
|
8
|
+
/**
|
|
9
|
+
* Gets validation options for a specific issuer
|
|
10
|
+
* This maintains backward compatibility with the old structure
|
|
11
|
+
*/
|
|
8
12
|
export declare const getValidationOptions: (issuer: string) => {
|
|
9
13
|
audience: string;
|
|
10
14
|
jwksUri: string;
|
|
11
15
|
} | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Backward compatible validationOptions object
|
|
18
|
+
* @deprecated Use getValidationOptions() or AuthProviderRegistry instead
|
|
19
|
+
*/
|
|
12
20
|
export declare const validationOptions: Record<string, {
|
|
13
21
|
audience: string;
|
|
14
22
|
jwksUri: string;
|
|
@@ -34,7 +42,13 @@ export declare class UserPayload {
|
|
|
34
42
|
family_name?: string;
|
|
35
43
|
[key: string]: unknown;
|
|
36
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Gets signing keys for JWT validation
|
|
47
|
+
*/
|
|
37
48
|
export declare const getSigningKeys: (issuer: string) => (header: JwtHeader, cb: SigningKeyCallback) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Extracts user information from JWT payload using the appropriate provider
|
|
51
|
+
*/
|
|
38
52
|
export declare const extractUserInfoFromPayload: (payload: JwtPayload) => {
|
|
39
53
|
email?: string;
|
|
40
54
|
firstName?: string;
|