@pax8-cta/core 0.1.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/LICENSE +198 -0
- package/dist/auth/device-code-login.d.ts +40 -0
- package/dist/auth/device-code-login.d.ts.map +1 -0
- package/dist/auth/device-code-login.js +59 -0
- package/dist/auth/device-code-login.js.map +1 -0
- package/dist/auth/gdap-client.d.ts +81 -0
- package/dist/auth/gdap-client.d.ts.map +1 -0
- package/dist/auth/gdap-client.js +128 -0
- package/dist/auth/gdap-client.js.map +1 -0
- package/dist/auth/index.d.ts +19 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +19 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/token-manager.d.ts +54 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +150 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +27 -0
- package/dist/client.js.map +1 -0
- package/dist/config/client.d.ts +24 -0
- package/dist/config/client.d.ts.map +1 -0
- package/dist/config/client.js +18 -0
- package/dist/config/client.js.map +1 -0
- package/dist/config/index.d.ts +18 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +18 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +81 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +271 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +751 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +556 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.d.ts +116 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +170 -0
- package/dist/constants.js.map +1 -0
- package/dist/dataverse/agent-resolver.d.ts +98 -0
- package/dist/dataverse/agent-resolver.d.ts.map +1 -0
- package/dist/dataverse/agent-resolver.js +185 -0
- package/dist/dataverse/agent-resolver.js.map +1 -0
- package/dist/dataverse/client.d.ts +104 -0
- package/dist/dataverse/client.d.ts.map +1 -0
- package/dist/dataverse/client.js +272 -0
- package/dist/dataverse/client.js.map +1 -0
- package/dist/dataverse/connection-refs.d.ts +115 -0
- package/dist/dataverse/connection-refs.d.ts.map +1 -0
- package/dist/dataverse/connection-refs.js +203 -0
- package/dist/dataverse/connection-refs.js.map +1 -0
- package/dist/dataverse/index.d.ts +20 -0
- package/dist/dataverse/index.d.ts.map +1 -0
- package/dist/dataverse/index.js +20 -0
- package/dist/dataverse/index.js.map +1 -0
- package/dist/dataverse/solution-ops.d.ts +100 -0
- package/dist/dataverse/solution-ops.d.ts.map +1 -0
- package/dist/dataverse/solution-ops.js +288 -0
- package/dist/dataverse/solution-ops.js.map +1 -0
- package/dist/errors.d.ts +171 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +178 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/mock/demo-data.d.ts +213 -0
- package/dist/mock/demo-data.d.ts.map +1 -0
- package/dist/mock/demo-data.js +1096 -0
- package/dist/mock/demo-data.js.map +1 -0
- package/dist/mock/demo-deployment-store.d.ts +77 -0
- package/dist/mock/demo-deployment-store.d.ts.map +1 -0
- package/dist/mock/demo-deployment-store.js +85 -0
- package/dist/mock/demo-deployment-store.js.map +1 -0
- package/dist/powerplatform/admin-client.d.ts +226 -0
- package/dist/powerplatform/admin-client.d.ts.map +1 -0
- package/dist/powerplatform/admin-client.js +315 -0
- package/dist/powerplatform/admin-client.js.map +1 -0
- package/dist/powerplatform/index.d.ts +18 -0
- package/dist/powerplatform/index.d.ts.map +1 -0
- package/dist/powerplatform/index.js +18 -0
- package/dist/powerplatform/index.js.map +1 -0
- package/dist/powerplatform/tenant-discovery.d.ts +100 -0
- package/dist/powerplatform/tenant-discovery.d.ts.map +1 -0
- package/dist/powerplatform/tenant-discovery.js +205 -0
- package/dist/powerplatform/tenant-discovery.js.map +1 -0
- package/dist/preconditions/check.d.ts +41 -0
- package/dist/preconditions/check.d.ts.map +1 -0
- package/dist/preconditions/check.js +173 -0
- package/dist/preconditions/check.js.map +1 -0
- package/dist/preconditions/index.d.ts +20 -0
- package/dist/preconditions/index.d.ts.map +1 -0
- package/dist/preconditions/index.js +20 -0
- package/dist/preconditions/index.js.map +1 -0
- package/dist/preconditions/loader.d.ts +33 -0
- package/dist/preconditions/loader.d.ts.map +1 -0
- package/dist/preconditions/loader.js +65 -0
- package/dist/preconditions/loader.js.map +1 -0
- package/dist/preconditions/schema.d.ts +103 -0
- package/dist/preconditions/schema.d.ts.map +1 -0
- package/dist/preconditions/schema.js +93 -0
- package/dist/preconditions/schema.js.map +1 -0
- package/dist/preconditions/types.d.ts +118 -0
- package/dist/preconditions/types.d.ts.map +1 -0
- package/dist/preconditions/types.js +17 -0
- package/dist/preconditions/types.js.map +1 -0
- package/dist/queue/index.d.ts +17 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +17 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/memory-queue.d.ts +86 -0
- package/dist/queue/memory-queue.d.ts.map +1 -0
- package/dist/queue/memory-queue.js +221 -0
- package/dist/queue/memory-queue.js.map +1 -0
- package/dist/services/audit-log.d.ts +59 -0
- package/dist/services/audit-log.d.ts.map +1 -0
- package/dist/services/audit-log.js +193 -0
- package/dist/services/audit-log.js.map +1 -0
- package/dist/services/auth-error-parser.d.ts +36 -0
- package/dist/services/auth-error-parser.d.ts.map +1 -0
- package/dist/services/auth-error-parser.js +90 -0
- package/dist/services/auth-error-parser.js.map +1 -0
- package/dist/services/deployment-doctor.d.ts +109 -0
- package/dist/services/deployment-doctor.d.ts.map +1 -0
- package/dist/services/deployment-doctor.js +476 -0
- package/dist/services/deployment-doctor.js.map +1 -0
- package/dist/services/deployment-notifications.d.ts +41 -0
- package/dist/services/deployment-notifications.d.ts.map +1 -0
- package/dist/services/deployment-notifications.js +161 -0
- package/dist/services/deployment-notifications.js.map +1 -0
- package/dist/services/deployment-progress.d.ts +89 -0
- package/dist/services/deployment-progress.d.ts.map +1 -0
- package/dist/services/deployment-progress.js +244 -0
- package/dist/services/deployment-progress.js.map +1 -0
- package/dist/services/deployment-service.d.ts +97 -0
- package/dist/services/deployment-service.d.ts.map +1 -0
- package/dist/services/deployment-service.js +375 -0
- package/dist/services/deployment-service.js.map +1 -0
- package/dist/services/drift-analyzer.d.ts +86 -0
- package/dist/services/drift-analyzer.d.ts.map +1 -0
- package/dist/services/drift-analyzer.js +273 -0
- package/dist/services/drift-analyzer.js.map +1 -0
- package/dist/services/environment-setup.d.ts +97 -0
- package/dist/services/environment-setup.d.ts.map +1 -0
- package/dist/services/environment-setup.js +250 -0
- package/dist/services/environment-setup.js.map +1 -0
- package/dist/services/health-check.d.ts +168 -0
- package/dist/services/health-check.d.ts.map +1 -0
- package/dist/services/health-check.js +705 -0
- package/dist/services/health-check.js.map +1 -0
- package/dist/services/index.d.ts +39 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +39 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/logger.d.ts +139 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +268 -0
- package/dist/services/logger.js.map +1 -0
- package/dist/services/notification-service.d.ts +55 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +184 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/risk-analyzer.d.ts +252 -0
- package/dist/services/risk-analyzer.d.ts.map +1 -0
- package/dist/services/risk-analyzer.js +866 -0
- package/dist/services/risk-analyzer.js.map +1 -0
- package/dist/services/rollback.d.ts +57 -0
- package/dist/services/rollback.d.ts.map +1 -0
- package/dist/services/rollback.js +270 -0
- package/dist/services/rollback.js.map +1 -0
- package/dist/services/scheduler.d.ts +80 -0
- package/dist/services/scheduler.d.ts.map +1 -0
- package/dist/services/scheduler.js +350 -0
- package/dist/services/scheduler.js.map +1 -0
- package/dist/services/secrets.d.ts +31 -0
- package/dist/services/secrets.d.ts.map +1 -0
- package/dist/services/secrets.js +206 -0
- package/dist/services/secrets.js.map +1 -0
- package/dist/services/settings-service.d.ts +132 -0
- package/dist/services/settings-service.d.ts.map +1 -0
- package/dist/services/settings-service.js +378 -0
- package/dist/services/settings-service.js.map +1 -0
- package/dist/services/solution-diff.d.ts +127 -0
- package/dist/services/solution-diff.d.ts.map +1 -0
- package/dist/services/solution-diff.js +260 -0
- package/dist/services/solution-diff.js.map +1 -0
- package/dist/services/solution-mode-detector.d.ts +35 -0
- package/dist/services/solution-mode-detector.d.ts.map +1 -0
- package/dist/services/solution-mode-detector.js +84 -0
- package/dist/services/solution-mode-detector.js.map +1 -0
- package/dist/services/tenant-resolver.d.ts +55 -0
- package/dist/services/tenant-resolver.d.ts.map +1 -0
- package/dist/services/tenant-resolver.js +126 -0
- package/dist/services/tenant-resolver.js.map +1 -0
- package/dist/services/unmanaged-customizations.d.ts +104 -0
- package/dist/services/unmanaged-customizations.d.ts.map +1 -0
- package/dist/services/unmanaged-customizations.js +521 -0
- package/dist/services/unmanaged-customizations.js.map +1 -0
- package/dist/services/url-templater.d.ts +184 -0
- package/dist/services/url-templater.d.ts.map +1 -0
- package/dist/services/url-templater.js +327 -0
- package/dist/services/url-templater.js.map +1 -0
- package/dist/services/version-checker.d.ts +108 -0
- package/dist/services/version-checker.d.ts.map +1 -0
- package/dist/services/version-checker.js +403 -0
- package/dist/services/version-checker.js.map +1 -0
- package/dist/services/waves.d.ts +90 -0
- package/dist/services/waves.d.ts.map +1 -0
- package/dist/services/waves.js +222 -0
- package/dist/services/waves.js.map +1 -0
- package/dist/services/webhook.d.ts +95 -0
- package/dist/services/webhook.d.ts.map +1 -0
- package/dist/services/webhook.js +244 -0
- package/dist/services/webhook.js.map +1 -0
- package/dist/utils/deployment-tools.d.ts +110 -0
- package/dist/utils/deployment-tools.d.ts.map +1 -0
- package/dist/utils/deployment-tools.js +121 -0
- package/dist/utils/deployment-tools.js.map +1 -0
- package/dist/utils/index.d.ts +17 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2024 Pax8, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { TokenManager } from "../auth/token-manager.js";
|
|
17
|
+
import { TenantConfig } from "../config/schema.js";
|
|
18
|
+
/** Types of components that can have unmanaged customizations */
|
|
19
|
+
export type CustomizationComponentType = "flow" | "entity" | "field" | "form" | "view" | "security_role" | "plugin" | "web_resource" | "other";
|
|
20
|
+
/** A single unmanaged customization detected in a tenant */
|
|
21
|
+
export interface UnmanagedCustomization {
|
|
22
|
+
/** Component unique identifier */
|
|
23
|
+
componentId: string;
|
|
24
|
+
/** Display name of the component */
|
|
25
|
+
displayName: string;
|
|
26
|
+
/** Logical name (e.g., table logical name, flow name) */
|
|
27
|
+
logicalName: string;
|
|
28
|
+
/** Type of component */
|
|
29
|
+
componentType: CustomizationComponentType;
|
|
30
|
+
/** Which managed solution this component belongs to */
|
|
31
|
+
managedSolutionName: string;
|
|
32
|
+
/** Description of the customization detected */
|
|
33
|
+
description: string;
|
|
34
|
+
}
|
|
35
|
+
/** Result of scanning a tenant for unmanaged customizations */
|
|
36
|
+
export interface UnmanagedCustomizationResult {
|
|
37
|
+
tenantId: string;
|
|
38
|
+
tenantName: string;
|
|
39
|
+
/** Total count of unmanaged customizations found */
|
|
40
|
+
totalCustomizations: number;
|
|
41
|
+
/** Breakdown by component type */
|
|
42
|
+
byType: Record<CustomizationComponentType, number>;
|
|
43
|
+
/** List of detected customizations */
|
|
44
|
+
customizations: UnmanagedCustomization[];
|
|
45
|
+
/** Risk level based on customization count and type */
|
|
46
|
+
riskLevel: "none" | "low" | "medium" | "high";
|
|
47
|
+
/** Human-readable risk summary */
|
|
48
|
+
riskSummary: string;
|
|
49
|
+
/** When the scan was performed */
|
|
50
|
+
scannedAt: string;
|
|
51
|
+
/** Error if the scan failed */
|
|
52
|
+
error?: string;
|
|
53
|
+
}
|
|
54
|
+
/** Dataverse API response shape for solution component summaries */
|
|
55
|
+
export interface SolutionComponentSummaryRecord {
|
|
56
|
+
msdyn_componentlogicalname: string;
|
|
57
|
+
msdyn_name: string;
|
|
58
|
+
msdyn_componenttype: number;
|
|
59
|
+
msdyn_ismanaged: boolean;
|
|
60
|
+
msdyn_solutionid: string;
|
|
61
|
+
msdyn_componentid: string;
|
|
62
|
+
msdyn_primaryentityname?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Calculate risk level based on unmanaged customizations
|
|
66
|
+
*/
|
|
67
|
+
export declare function calculateCustomizationRisk(customizations: UnmanagedCustomization[]): {
|
|
68
|
+
riskLevel: UnmanagedCustomizationResult["riskLevel"];
|
|
69
|
+
riskSummary: string;
|
|
70
|
+
};
|
|
71
|
+
export declare class UnmanagedCustomizationDetector {
|
|
72
|
+
/**
|
|
73
|
+
* Scan a single tenant for unmanaged customizations
|
|
74
|
+
*/
|
|
75
|
+
scanTenant(tenant: TenantConfig, managedSolutionName: string, tokenManager?: TokenManager): Promise<UnmanagedCustomizationResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Scan multiple tenants in parallel
|
|
78
|
+
*/
|
|
79
|
+
scanMultipleTenants(tenants: TenantConfig[], managedSolutionName: string, tokenManager?: TokenManager): Promise<UnmanagedCustomizationResult[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Query Dataverse for unmanaged solution layers on managed solution components
|
|
82
|
+
*/
|
|
83
|
+
private queryUnmanagedLayers;
|
|
84
|
+
private describeCustomization;
|
|
85
|
+
private countByType;
|
|
86
|
+
private emptyByType;
|
|
87
|
+
}
|
|
88
|
+
export declare const unmanagedCustomizationDetector: UnmanagedCustomizationDetector;
|
|
89
|
+
/**
|
|
90
|
+
* Get demo unmanaged customizations for a specific tenant
|
|
91
|
+
*/
|
|
92
|
+
export declare function getDemoUnmanagedCustomizations(tenantId: string, managedSolutionName: string): UnmanagedCustomizationResult;
|
|
93
|
+
/**
|
|
94
|
+
* Get demo unmanaged customization summary for all enabled tenants
|
|
95
|
+
*/
|
|
96
|
+
export declare function getDemoCustomizationSummary(managedSolutionName: string): {
|
|
97
|
+
totalTenants: number;
|
|
98
|
+
tenantsWithCustomizations: number;
|
|
99
|
+
tenantsClean: number;
|
|
100
|
+
totalCustomizations: number;
|
|
101
|
+
highRiskTenants: string[];
|
|
102
|
+
results: UnmanagedCustomizationResult[];
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=unmanaged-customizations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unmanaged-customizations.d.ts","sourceRoot":"","sources":["../../src/services/unmanaged-customizations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2024 Pax8, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Unmanaged Customization Detection Service
|
|
18
|
+
*
|
|
19
|
+
* Detects unmanaged customizations (solution layers not part of any managed solution)
|
|
20
|
+
* in customer tenants. Unmanaged customizations are a high-risk factor for drift
|
|
21
|
+
* because managed solution upgrades can overwrite or conflict with them.
|
|
22
|
+
*
|
|
23
|
+
* Dataverse API: queries msdyn_solutioncomponentsummaries for unmanaged layers
|
|
24
|
+
* on components owned by the managed solution.
|
|
25
|
+
*/
|
|
26
|
+
import { DataverseClient } from "../dataverse/client.js";
|
|
27
|
+
import { DEMO_TENANTS } from "../mock/demo-data.js";
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Component type mapping (Dataverse component type codes)
|
|
30
|
+
// ============================================================================
|
|
31
|
+
const COMPONENT_TYPE_MAP = {
|
|
32
|
+
1: "entity", // Entity
|
|
33
|
+
2: "field", // Attribute (field)
|
|
34
|
+
24: "form", // Form
|
|
35
|
+
26: "view", // Saved Query (view)
|
|
36
|
+
29: "flow", // Workflow / Cloud Flow
|
|
37
|
+
76: "security_role", // Security Role
|
|
38
|
+
91: "plugin", // Plugin Assembly
|
|
39
|
+
61: "web_resource", // Web Resource
|
|
40
|
+
};
|
|
41
|
+
function mapComponentType(typeCode) {
|
|
42
|
+
return COMPONENT_TYPE_MAP[typeCode] || "other";
|
|
43
|
+
}
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Risk calculation
|
|
46
|
+
// ============================================================================
|
|
47
|
+
/**
|
|
48
|
+
* Calculate risk level based on unmanaged customizations
|
|
49
|
+
*/
|
|
50
|
+
export function calculateCustomizationRisk(customizations) {
|
|
51
|
+
if (customizations.length === 0) {
|
|
52
|
+
return { riskLevel: "none", riskSummary: "No unmanaged customizations detected" };
|
|
53
|
+
}
|
|
54
|
+
// High-risk component types that are most likely to conflict with managed updates
|
|
55
|
+
const highRiskTypes = ["flow", "security_role", "plugin"];
|
|
56
|
+
const highRiskCount = customizations.filter((c) => highRiskTypes.includes(c.componentType)).length;
|
|
57
|
+
const totalCount = customizations.length;
|
|
58
|
+
if (highRiskCount >= 3 || totalCount >= 10) {
|
|
59
|
+
return {
|
|
60
|
+
riskLevel: "high",
|
|
61
|
+
riskSummary: `${totalCount} unmanaged customizations detected (${highRiskCount} high-risk). ` +
|
|
62
|
+
`Managed solution upgrade may overwrite or conflict with these changes.`,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (highRiskCount >= 1 || totalCount >= 5) {
|
|
66
|
+
return {
|
|
67
|
+
riskLevel: "medium",
|
|
68
|
+
riskSummary: `${totalCount} unmanaged customizations detected. ` +
|
|
69
|
+
`Review before upgrading managed solution.`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
riskLevel: "low",
|
|
74
|
+
riskSummary: `${totalCount} minor unmanaged customizations detected. ` +
|
|
75
|
+
`Low risk of conflict with managed solution upgrade.`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// ============================================================================
|
|
79
|
+
// Main Service
|
|
80
|
+
// ============================================================================
|
|
81
|
+
export class UnmanagedCustomizationDetector {
|
|
82
|
+
/**
|
|
83
|
+
* Scan a single tenant for unmanaged customizations
|
|
84
|
+
*/
|
|
85
|
+
async scanTenant(tenant, managedSolutionName, tokenManager) {
|
|
86
|
+
// Demo mode
|
|
87
|
+
if (process.env.DEMO_MODE === "true" || !tokenManager) {
|
|
88
|
+
return getDemoUnmanagedCustomizations(tenant.tenantId, managedSolutionName);
|
|
89
|
+
}
|
|
90
|
+
// Production mode - query Dataverse
|
|
91
|
+
try {
|
|
92
|
+
const client = new DataverseClient({
|
|
93
|
+
environmentUrl: tenant.environmentUrl,
|
|
94
|
+
tokenManager,
|
|
95
|
+
clientId: tokenManager.getClientId(),
|
|
96
|
+
});
|
|
97
|
+
const customizations = await this.queryUnmanagedLayers(client, managedSolutionName);
|
|
98
|
+
const { riskLevel, riskSummary } = calculateCustomizationRisk(customizations);
|
|
99
|
+
const byType = this.countByType(customizations);
|
|
100
|
+
return {
|
|
101
|
+
tenantId: tenant.tenantId,
|
|
102
|
+
tenantName: tenant.name,
|
|
103
|
+
totalCustomizations: customizations.length,
|
|
104
|
+
byType,
|
|
105
|
+
customizations,
|
|
106
|
+
riskLevel,
|
|
107
|
+
riskSummary,
|
|
108
|
+
scannedAt: new Date().toISOString(),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
113
|
+
return {
|
|
114
|
+
tenantId: tenant.tenantId,
|
|
115
|
+
tenantName: tenant.name,
|
|
116
|
+
totalCustomizations: 0,
|
|
117
|
+
byType: this.emptyByType(),
|
|
118
|
+
customizations: [],
|
|
119
|
+
riskLevel: "none",
|
|
120
|
+
riskSummary: "Scan failed - unable to determine customization status",
|
|
121
|
+
scannedAt: new Date().toISOString(),
|
|
122
|
+
error: errorMessage,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Scan multiple tenants in parallel
|
|
128
|
+
*/
|
|
129
|
+
async scanMultipleTenants(tenants, managedSolutionName, tokenManager) {
|
|
130
|
+
const CONCURRENCY = 5;
|
|
131
|
+
const results = [];
|
|
132
|
+
for (let i = 0; i < tenants.length; i += CONCURRENCY) {
|
|
133
|
+
const batch = tenants.slice(i, i + CONCURRENCY);
|
|
134
|
+
const batchResults = await Promise.all(batch.map((t) => this.scanTenant(t, managedSolutionName, tokenManager)));
|
|
135
|
+
results.push(...batchResults);
|
|
136
|
+
}
|
|
137
|
+
return results;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Query Dataverse for unmanaged solution layers on managed solution components
|
|
141
|
+
*/
|
|
142
|
+
async queryUnmanagedLayers(client, managedSolutionName) {
|
|
143
|
+
// First, get the managed solution ID
|
|
144
|
+
const solution = await client.getSolutionByName(managedSolutionName);
|
|
145
|
+
if (!solution) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
// Query solution component summaries for unmanaged layers
|
|
149
|
+
const result = await client.get("/msdyn_solutioncomponentsummaries", {
|
|
150
|
+
$filter: `msdyn_solutionid eq '${solution.solutionid}' and msdyn_ismanaged eq false`,
|
|
151
|
+
$select: "msdyn_componentlogicalname,msdyn_name,msdyn_componenttype,msdyn_ismanaged,msdyn_solutionid,msdyn_componentid,msdyn_primaryentityname",
|
|
152
|
+
});
|
|
153
|
+
return result.value.map((record) => {
|
|
154
|
+
const componentType = mapComponentType(record.msdyn_componenttype);
|
|
155
|
+
return {
|
|
156
|
+
componentId: record.msdyn_componentid,
|
|
157
|
+
displayName: record.msdyn_name || record.msdyn_componentlogicalname,
|
|
158
|
+
logicalName: record.msdyn_componentlogicalname,
|
|
159
|
+
componentType,
|
|
160
|
+
managedSolutionName,
|
|
161
|
+
description: this.describeCustomization(componentType, record),
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
describeCustomization(componentType, record) {
|
|
166
|
+
switch (componentType) {
|
|
167
|
+
case "flow":
|
|
168
|
+
return `Modified cloud flow: ${record.msdyn_name || record.msdyn_componentlogicalname}`;
|
|
169
|
+
case "entity":
|
|
170
|
+
return `Custom entity modifications on ${record.msdyn_primaryentityname || record.msdyn_componentlogicalname}`;
|
|
171
|
+
case "field":
|
|
172
|
+
return `Added/modified field on ${record.msdyn_primaryentityname || "entity"}`;
|
|
173
|
+
case "form":
|
|
174
|
+
return `Modified form for ${record.msdyn_primaryentityname || "entity"}`;
|
|
175
|
+
case "view":
|
|
176
|
+
return `Modified view for ${record.msdyn_primaryentityname || "entity"}`;
|
|
177
|
+
case "security_role":
|
|
178
|
+
return `Modified security role: ${record.msdyn_name || record.msdyn_componentlogicalname}`;
|
|
179
|
+
case "plugin":
|
|
180
|
+
return `Custom plugin: ${record.msdyn_name || record.msdyn_componentlogicalname}`;
|
|
181
|
+
case "web_resource":
|
|
182
|
+
return `Modified web resource: ${record.msdyn_name || record.msdyn_componentlogicalname}`;
|
|
183
|
+
default:
|
|
184
|
+
return `Unmanaged component: ${record.msdyn_name || record.msdyn_componentlogicalname}`;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
countByType(customizations) {
|
|
188
|
+
const counts = this.emptyByType();
|
|
189
|
+
for (const c of customizations) {
|
|
190
|
+
counts[c.componentType]++;
|
|
191
|
+
}
|
|
192
|
+
return counts;
|
|
193
|
+
}
|
|
194
|
+
emptyByType() {
|
|
195
|
+
return {
|
|
196
|
+
flow: 0,
|
|
197
|
+
entity: 0,
|
|
198
|
+
field: 0,
|
|
199
|
+
form: 0,
|
|
200
|
+
view: 0,
|
|
201
|
+
security_role: 0,
|
|
202
|
+
plugin: 0,
|
|
203
|
+
web_resource: 0,
|
|
204
|
+
other: 0,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// ============================================================================
|
|
209
|
+
// Singleton
|
|
210
|
+
// ============================================================================
|
|
211
|
+
export const unmanagedCustomizationDetector = new UnmanagedCustomizationDetector();
|
|
212
|
+
// ============================================================================
|
|
213
|
+
// Demo Mode Data
|
|
214
|
+
// ============================================================================
|
|
215
|
+
/**
|
|
216
|
+
* Deterministic demo data for unmanaged customizations.
|
|
217
|
+
* Some tenants have customizations, some don't, providing realistic variety.
|
|
218
|
+
*/
|
|
219
|
+
const DEMO_CUSTOMIZATIONS = {
|
|
220
|
+
// Contoso Corporation - enterprise tenant with several customizations (high risk)
|
|
221
|
+
"11111111-1111-1111-1111-111111111111": [
|
|
222
|
+
{
|
|
223
|
+
componentId: "cust-001",
|
|
224
|
+
displayName: "Custom Escalation Flow",
|
|
225
|
+
logicalName: "contoso_customescalationflow",
|
|
226
|
+
componentType: "flow",
|
|
227
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
228
|
+
description: "Modified cloud flow: Custom Escalation Flow",
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
componentId: "cust-002",
|
|
232
|
+
displayName: "Priority Field",
|
|
233
|
+
logicalName: "contoso_priorityfield",
|
|
234
|
+
componentType: "field",
|
|
235
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
236
|
+
description: "Added/modified field on incident",
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
componentId: "cust-003",
|
|
240
|
+
displayName: "VIP Customer View",
|
|
241
|
+
logicalName: "contoso_vipcustomerview",
|
|
242
|
+
componentType: "view",
|
|
243
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
244
|
+
description: "Modified view for incident",
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
componentId: "cust-004",
|
|
248
|
+
displayName: "Custom Security Role - Support Lead",
|
|
249
|
+
logicalName: "contoso_supportleadrole",
|
|
250
|
+
componentType: "security_role",
|
|
251
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
252
|
+
description: "Modified security role: Custom Security Role - Support Lead",
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
componentId: "cust-005",
|
|
256
|
+
displayName: "After-hours Routing Flow",
|
|
257
|
+
logicalName: "contoso_afterhoursrouting",
|
|
258
|
+
componentType: "flow",
|
|
259
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
260
|
+
description: "Modified cloud flow: After-hours Routing Flow",
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
componentId: "cust-006",
|
|
264
|
+
displayName: "Custom Ticket Form",
|
|
265
|
+
logicalName: "contoso_customticketform",
|
|
266
|
+
componentType: "form",
|
|
267
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
268
|
+
description: "Modified form for incident",
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
// Fabrikam Inc - a few minor customizations (medium risk)
|
|
272
|
+
"22222222-2222-2222-2222-222222222222": [
|
|
273
|
+
{
|
|
274
|
+
componentId: "cust-010",
|
|
275
|
+
displayName: "Custom Dashboard View",
|
|
276
|
+
logicalName: "fabrikam_dashboardview",
|
|
277
|
+
componentType: "view",
|
|
278
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
279
|
+
description: "Modified view for account",
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
componentId: "cust-011",
|
|
283
|
+
displayName: "Additional Contact Field",
|
|
284
|
+
logicalName: "fabrikam_altcontactfield",
|
|
285
|
+
componentType: "field",
|
|
286
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
287
|
+
description: "Added/modified field on contact",
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
componentId: "cust-012",
|
|
291
|
+
displayName: "Custom Notification Flow",
|
|
292
|
+
logicalName: "fabrikam_notificationflow",
|
|
293
|
+
componentType: "flow",
|
|
294
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
295
|
+
description: "Modified cloud flow: Custom Notification Flow",
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
// Adventure Works - no customizations (clean)
|
|
299
|
+
"33333333-3333-3333-3333-333333333333": [],
|
|
300
|
+
// Northwind Traders - minimal customizations (low risk)
|
|
301
|
+
"44444444-4444-4444-4444-444444444444": [
|
|
302
|
+
{
|
|
303
|
+
componentId: "cust-020",
|
|
304
|
+
displayName: "Extra Notes Field",
|
|
305
|
+
logicalName: "northwind_notesfield",
|
|
306
|
+
componentType: "field",
|
|
307
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
308
|
+
description: "Added/modified field on incident",
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
// Woodgrove Bank - heavy customizations (high risk, finance regulations)
|
|
312
|
+
"55555555-5555-5555-5555-555555555555": [
|
|
313
|
+
{
|
|
314
|
+
componentId: "cust-030",
|
|
315
|
+
displayName: "Compliance Check Flow",
|
|
316
|
+
logicalName: "woodgrove_complianceflow",
|
|
317
|
+
componentType: "flow",
|
|
318
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
319
|
+
description: "Modified cloud flow: Compliance Check Flow",
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
componentId: "cust-031",
|
|
323
|
+
displayName: "Audit Trail Plugin",
|
|
324
|
+
logicalName: "woodgrove_auditplugin",
|
|
325
|
+
componentType: "plugin",
|
|
326
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
327
|
+
description: "Custom plugin: Audit Trail Plugin",
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
componentId: "cust-032",
|
|
331
|
+
displayName: "Compliance Officer Role",
|
|
332
|
+
logicalName: "woodgrove_compliancerole",
|
|
333
|
+
componentType: "security_role",
|
|
334
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
335
|
+
description: "Modified security role: Compliance Officer Role",
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
componentId: "cust-033",
|
|
339
|
+
displayName: "Regulatory Hold Flow",
|
|
340
|
+
logicalName: "woodgrove_regholdflow",
|
|
341
|
+
componentType: "flow",
|
|
342
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
343
|
+
description: "Modified cloud flow: Regulatory Hold Flow",
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
componentId: "cust-034",
|
|
347
|
+
displayName: "Risk Assessment Form",
|
|
348
|
+
logicalName: "woodgrove_riskform",
|
|
349
|
+
componentType: "form",
|
|
350
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
351
|
+
description: "Modified form for account",
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
componentId: "cust-035",
|
|
355
|
+
displayName: "Customer Risk Score Field",
|
|
356
|
+
logicalName: "woodgrove_riskscorefield",
|
|
357
|
+
componentType: "field",
|
|
358
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
359
|
+
description: "Added/modified field on account",
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
componentId: "cust-036",
|
|
363
|
+
displayName: "KYC Verification Flow",
|
|
364
|
+
logicalName: "woodgrove_kycflow",
|
|
365
|
+
componentType: "flow",
|
|
366
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
367
|
+
description: "Modified cloud flow: KYC Verification Flow",
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
componentId: "cust-037",
|
|
371
|
+
displayName: "Transaction Monitor Web Resource",
|
|
372
|
+
logicalName: "woodgrove_txnmonitor",
|
|
373
|
+
componentType: "web_resource",
|
|
374
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
375
|
+
description: "Modified web resource: Transaction Monitor Web Resource",
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
componentId: "cust-038",
|
|
379
|
+
displayName: "Fraud Detection Plugin",
|
|
380
|
+
logicalName: "woodgrove_fraudplugin",
|
|
381
|
+
componentType: "plugin",
|
|
382
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
383
|
+
description: "Custom plugin: Fraud Detection Plugin",
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
componentId: "cust-039",
|
|
387
|
+
displayName: "Branch Manager Role",
|
|
388
|
+
logicalName: "woodgrove_branchmgrrole",
|
|
389
|
+
componentType: "security_role",
|
|
390
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
391
|
+
description: "Modified security role: Branch Manager Role",
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
// Tailspin Toys - no customizations
|
|
395
|
+
"66666666-6666-6666-6666-666666666666": [],
|
|
396
|
+
// Litware Inc - some customizations (medium risk)
|
|
397
|
+
"88888888-8888-8888-8888-888888888888": [
|
|
398
|
+
{
|
|
399
|
+
componentId: "cust-040",
|
|
400
|
+
displayName: "Tech Support Routing Flow",
|
|
401
|
+
logicalName: "litware_techrouting",
|
|
402
|
+
componentType: "flow",
|
|
403
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
404
|
+
description: "Modified cloud flow: Tech Support Routing Flow",
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
componentId: "cust-041",
|
|
408
|
+
displayName: "Product Category Field",
|
|
409
|
+
logicalName: "litware_productcatfield",
|
|
410
|
+
componentType: "field",
|
|
411
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
412
|
+
description: "Added/modified field on incident",
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
componentId: "cust-042",
|
|
416
|
+
displayName: "Engineering Escalation Role",
|
|
417
|
+
logicalName: "litware_engrole",
|
|
418
|
+
componentType: "security_role",
|
|
419
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
420
|
+
description: "Modified security role: Engineering Escalation Role",
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
componentId: "cust-043",
|
|
424
|
+
displayName: "SLA Tracker View",
|
|
425
|
+
logicalName: "litware_slaview",
|
|
426
|
+
componentType: "view",
|
|
427
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
428
|
+
description: "Modified view for incident",
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
componentId: "cust-044",
|
|
432
|
+
displayName: "Custom Incident Form",
|
|
433
|
+
logicalName: "litware_incidentform",
|
|
434
|
+
componentType: "form",
|
|
435
|
+
managedSolutionName: "CustomerServiceAgent",
|
|
436
|
+
description: "Modified form for incident",
|
|
437
|
+
},
|
|
438
|
+
],
|
|
439
|
+
// Proseware - no customizations
|
|
440
|
+
"99999999-9999-9999-9999-999999999999": [],
|
|
441
|
+
// Coho Vineyard - no customizations
|
|
442
|
+
"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa": [],
|
|
443
|
+
};
|
|
444
|
+
/**
|
|
445
|
+
* Get demo unmanaged customizations for a specific tenant
|
|
446
|
+
*/
|
|
447
|
+
export function getDemoUnmanagedCustomizations(tenantId, managedSolutionName) {
|
|
448
|
+
const tenant = DEMO_TENANTS.find((t) => t.tenantId === tenantId);
|
|
449
|
+
if (!tenant) {
|
|
450
|
+
return {
|
|
451
|
+
tenantId,
|
|
452
|
+
tenantName: "Unknown",
|
|
453
|
+
totalCustomizations: 0,
|
|
454
|
+
byType: {
|
|
455
|
+
flow: 0,
|
|
456
|
+
entity: 0,
|
|
457
|
+
field: 0,
|
|
458
|
+
form: 0,
|
|
459
|
+
view: 0,
|
|
460
|
+
security_role: 0,
|
|
461
|
+
plugin: 0,
|
|
462
|
+
web_resource: 0,
|
|
463
|
+
other: 0,
|
|
464
|
+
},
|
|
465
|
+
customizations: [],
|
|
466
|
+
riskLevel: "none",
|
|
467
|
+
riskSummary: "Tenant not found",
|
|
468
|
+
scannedAt: new Date().toISOString(),
|
|
469
|
+
error: "Tenant not found",
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
const customizations = (DEMO_CUSTOMIZATIONS[tenantId] || []).map((c) => ({
|
|
473
|
+
...c,
|
|
474
|
+
managedSolutionName,
|
|
475
|
+
}));
|
|
476
|
+
const { riskLevel, riskSummary } = calculateCustomizationRisk(customizations);
|
|
477
|
+
// Count by type
|
|
478
|
+
const byType = {
|
|
479
|
+
flow: 0,
|
|
480
|
+
entity: 0,
|
|
481
|
+
field: 0,
|
|
482
|
+
form: 0,
|
|
483
|
+
view: 0,
|
|
484
|
+
security_role: 0,
|
|
485
|
+
plugin: 0,
|
|
486
|
+
web_resource: 0,
|
|
487
|
+
other: 0,
|
|
488
|
+
};
|
|
489
|
+
for (const c of customizations) {
|
|
490
|
+
byType[c.componentType]++;
|
|
491
|
+
}
|
|
492
|
+
return {
|
|
493
|
+
tenantId,
|
|
494
|
+
tenantName: tenant.name,
|
|
495
|
+
totalCustomizations: customizations.length,
|
|
496
|
+
byType,
|
|
497
|
+
customizations,
|
|
498
|
+
riskLevel,
|
|
499
|
+
riskSummary,
|
|
500
|
+
scannedAt: new Date().toISOString(),
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Get demo unmanaged customization summary for all enabled tenants
|
|
505
|
+
*/
|
|
506
|
+
export function getDemoCustomizationSummary(managedSolutionName) {
|
|
507
|
+
const enabledTenants = DEMO_TENANTS.filter((t) => t.enabled);
|
|
508
|
+
const results = enabledTenants.map((t) => getDemoUnmanagedCustomizations(t.tenantId, managedSolutionName));
|
|
509
|
+
const tenantsWithCustomizations = results.filter((r) => r.totalCustomizations > 0).length;
|
|
510
|
+
const totalCustomizations = results.reduce((sum, r) => sum + r.totalCustomizations, 0);
|
|
511
|
+
const highRiskTenants = results.filter((r) => r.riskLevel === "high").map((r) => r.tenantName);
|
|
512
|
+
return {
|
|
513
|
+
totalTenants: enabledTenants.length,
|
|
514
|
+
tenantsWithCustomizations,
|
|
515
|
+
tenantsClean: enabledTenants.length - tenantsWithCustomizations,
|
|
516
|
+
totalCustomizations,
|
|
517
|
+
highRiskTenants,
|
|
518
|
+
results,
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
//# sourceMappingURL=unmanaged-customizations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unmanaged-customizations.js","sourceRoot":"","sources":["../../src/services/unmanaged-customizations.ts"],"names":[],"mappings":"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"}
|