@mindline/sync 1.0.89 → 1.0.91
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/.vs/VSWorkspaceState.json +4 -2
- package/.vs/slnx.sqlite +0 -0
- package/.vs/sync/CopilotIndices/17.14.260.54502/CodeChunks.db +0 -0
- package/.vs/sync/CopilotIndices/17.14.260.54502/SemanticSymbols.db +0 -0
- package/.vs/sync/FileContentIndex/{6ae8ea19-641b-4811-a4ef-e70ea6cb6339.vsidx → 0f447c8e-f707-40c3-aa4c-30bfeab10f57.vsidx} +0 -0
- package/.vs/sync/FileContentIndex/b3821e23-fbe8-43ca-9167-2deeb211602b.vsidx +0 -0
- package/.vs/sync/v17/.wsuo +0 -0
- package/.vs/sync/v17/DocumentLayout.backup.json +52 -2
- package/.vs/sync/v17/DocumentLayout.json +73 -22
- package/dist/actors.json.d.ts +22 -0
- package/dist/configs.json.d.ts +3 -0
- package/dist/index.d.ts +348 -0
- package/dist/resources.json.d.ts +60 -0
- package/dist/sync.es.js +4214 -0
- package/dist/sync.es.js.map +1 -0
- package/dist/sync.umd.js +54 -0
- package/dist/sync.umd.js.map +1 -0
- package/dist/syncmilestones.json.d.ts +25 -0
- package/dist/tenants.json.d.ts +13 -0
- package/dist/users.json.d.ts +15 -0
- package/dist/workspaces.json.d.ts +12 -0
- package/package.json +20 -12
- package/{index.ts → src/index.ts} +206 -148
- package/tsconfig.json +11 -14
- package/vite.config.ts +31 -0
- package/.vs/sync/FileContentIndex/9d767116-a2e8-4565-8920-26919169781d.vsidx +0 -0
- package/tasks.ts +0 -55
- /package/{README.md → src/README.md} +0 -0
- /package/{actors.json → src/actors.json} +0 -0
- /package/{configs.json → src/configs.json} +0 -0
- /package/{configs2.json → src/configs2.json} +0 -0
- /package/{index.d.ts → src/index.d.ts} +0 -0
- /package/{mockconfig.json → src/mockconfig.json} +0 -0
- /package/{resources.json → src/resources.json} +0 -0
- /package/{syncmilestones.json → src/syncmilestones.json} +0 -0
- /package/{tenants.json → src/tenants.json} +0 -0
- /package/{tenants2.json → src/tenants2.json} +0 -0
- /package/{users.json → src/users.json} +0 -0
- /package/{users2.json → src/users2.json} +0 -0
- /package/{workspaces.json → src/workspaces.json} +0 -0
- /package/{workspaces2.json → src/workspaces2.json} +0 -0
|
@@ -3,17 +3,14 @@ import * as signalR from "@microsoft/signalr"
|
|
|
3
3
|
import { AccountInfo } from "@azure/msal-common";
|
|
4
4
|
import { IPublicClientApplication, AuthenticationResult } from "@azure/msal-browser"
|
|
5
5
|
import { deserializeArray } from 'class-transformer';
|
|
6
|
-
import {
|
|
7
|
-
import { version } from './package.json';
|
|
6
|
+
import { version } from '../package.json';
|
|
8
7
|
import users from "./users.json";
|
|
9
8
|
import tenants from "./tenants.json";
|
|
10
9
|
import configs from "./configs.json";
|
|
11
10
|
import workspaces from "./workspaces.json";
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import actors from './actors';
|
|
16
|
-
import { log } from "console";
|
|
11
|
+
import syncmilestones from './syncmilestones.json';
|
|
12
|
+
import resources from './resources.json';
|
|
13
|
+
import actors from './actors.json';
|
|
17
14
|
|
|
18
15
|
const FILTER_FIELD = "workspaceIDs";
|
|
19
16
|
// called by unit tests
|
|
@@ -103,16 +100,16 @@ export class graphConfig {
|
|
|
103
100
|
static authorityCNRegex: RegExp = /^(https:\/\/login\.partner\.microsoftonline\.cn\/)([\dA-Fa-f]{8}-[\dA-Fa-f]{4}-[\dA-Fa-f]{4}-[\dA-Fa-f]{4}-[\dA-Fa-f]{12})\/oauth2\/authorize$/;
|
|
104
101
|
};
|
|
105
102
|
export class Group {
|
|
106
|
-
id: string;
|
|
107
|
-
displayName: string;
|
|
108
|
-
description: string;
|
|
103
|
+
id: string = "";
|
|
104
|
+
displayName: string = "";
|
|
105
|
+
description: string = "";
|
|
109
106
|
}
|
|
110
107
|
export class UserScope {
|
|
111
|
-
group: string;
|
|
112
|
-
value: string;
|
|
113
|
-
consented: boolean;
|
|
114
|
-
removable: boolean;
|
|
115
|
-
expanded: string;
|
|
108
|
+
group: string = "";
|
|
109
|
+
value: string = "";
|
|
110
|
+
consented: boolean = false;
|
|
111
|
+
removable: boolean = false;
|
|
112
|
+
expanded: string = "";
|
|
116
113
|
static compareByValue(a: UserScope, b: UserScope): number {
|
|
117
114
|
return a.value.localeCompare(b.value);
|
|
118
115
|
}
|
|
@@ -267,6 +264,7 @@ export class Config {
|
|
|
267
264
|
constructor() {
|
|
268
265
|
this.id = "";
|
|
269
266
|
this.name = "";
|
|
267
|
+
this.workspaceId = "";
|
|
270
268
|
this.description = "";
|
|
271
269
|
this.tenants = new Array();
|
|
272
270
|
this.isEnabled = false;
|
|
@@ -285,6 +283,7 @@ export class Workspace {
|
|
|
285
283
|
constructor() {
|
|
286
284
|
this.id = "";
|
|
287
285
|
this.name = "";
|
|
286
|
+
this.ownerid = "";
|
|
288
287
|
this.associatedUsers = new Array();
|
|
289
288
|
this.associatedTenants = new Array();
|
|
290
289
|
this.associatedConfigs = new Array();
|
|
@@ -292,10 +291,10 @@ export class Workspace {
|
|
|
292
291
|
}
|
|
293
292
|
}
|
|
294
293
|
// check for localStorage availability
|
|
295
|
-
function storageAvailable(
|
|
294
|
+
function storageAvailable() {
|
|
296
295
|
let storage;
|
|
297
296
|
try {
|
|
298
|
-
storage = window
|
|
297
|
+
storage = window.localStorage;
|
|
299
298
|
const x = "__storage_test__";
|
|
300
299
|
storage.setItem(x, x);
|
|
301
300
|
storage.removeItem(x);
|
|
@@ -319,22 +318,22 @@ function storageAvailable(type) {
|
|
|
319
318
|
}
|
|
320
319
|
}
|
|
321
320
|
export class InitInfo {
|
|
322
|
-
version: string;
|
|
323
|
-
tab: number;
|
|
324
|
-
us: User[];
|
|
325
|
-
ts: Tenant[];
|
|
326
|
-
cs: Config[];
|
|
327
|
-
ws: Workspace[];
|
|
328
|
-
configlevelconsent_configid: string;
|
|
329
|
-
configlevelconsent_access: TenantConfigType;
|
|
330
|
-
constructor(bClearLocalStorage: boolean) {
|
|
321
|
+
version: string = "";
|
|
322
|
+
tab: number = 0;
|
|
323
|
+
us: User[] = [];
|
|
324
|
+
ts: Tenant[] = [];
|
|
325
|
+
cs: Config[] = [];
|
|
326
|
+
ws: Workspace[] = [];
|
|
327
|
+
configlevelconsent_configid: string = "";
|
|
328
|
+
configlevelconsent_access: TenantConfigType = TenantConfigType.sourcetarget;
|
|
329
|
+
constructor(bClearLocalStorage: boolean = false) {
|
|
331
330
|
this.init(bClearLocalStorage);
|
|
332
331
|
}
|
|
333
332
|
// get initial data from localStorage or file
|
|
334
333
|
init(bClearLocalStorage: boolean): void {
|
|
335
334
|
console.log(`Calling InitInfo::init(bClearLocalStorage: ${bClearLocalStorage ? "true" : "false"})`);
|
|
336
335
|
// if we have a non-zero value stored, read it from localStorage
|
|
337
|
-
if (storageAvailable(
|
|
336
|
+
if (storageAvailable()) {
|
|
338
337
|
let result = localStorage.getItem("InitInfo");
|
|
339
338
|
if (result != null && typeof result === "string" && result !== "") {
|
|
340
339
|
let initInfoString: string = result;
|
|
@@ -503,6 +502,59 @@ export class InitInfo {
|
|
|
503
502
|
}
|
|
504
503
|
}
|
|
505
504
|
}
|
|
505
|
+
const tasksData: any[] = [
|
|
506
|
+
{
|
|
507
|
+
id: 1,
|
|
508
|
+
task: "initialization",
|
|
509
|
+
start: "1970-01-01T00:00:00",
|
|
510
|
+
end: "1970-01-01T00:00:00",
|
|
511
|
+
expected: "0:22",
|
|
512
|
+
status: "not started",
|
|
513
|
+
expanded: true,
|
|
514
|
+
subtasks: [
|
|
515
|
+
{
|
|
516
|
+
id: 2,
|
|
517
|
+
task: "authenticate user",
|
|
518
|
+
start: "1970-01-01T00:00:00",
|
|
519
|
+
end: "1970-01-01T00:00:00",
|
|
520
|
+
expected: "0:01",
|
|
521
|
+
status: "not started"
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
id: 3,
|
|
525
|
+
task: "reload React",
|
|
526
|
+
start: "1970-01-01T00:00:00",
|
|
527
|
+
end: "1970-01-01T00:00:00",
|
|
528
|
+
expected: "0:07",
|
|
529
|
+
status: "not started"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
id: 4,
|
|
533
|
+
task: "GET tenant details",
|
|
534
|
+
start: "1970-01-01T00:00:00",
|
|
535
|
+
end: "1970-01-01T00:00:00",
|
|
536
|
+
expected: "0:01",
|
|
537
|
+
status: "not started"
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
id: 5,
|
|
541
|
+
task: "POST config init",
|
|
542
|
+
start: "1970-01-01T00:00:00",
|
|
543
|
+
end: "1970-01-01T00:00:00",
|
|
544
|
+
expected: "0:10",
|
|
545
|
+
status: "not started"
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
id: 6,
|
|
549
|
+
task: "GET workspaces",
|
|
550
|
+
start: "1970-01-01T00:00:00",
|
|
551
|
+
end: "1970-01-01T00:00:00",
|
|
552
|
+
expected: "0:04",
|
|
553
|
+
status: "not started"
|
|
554
|
+
}
|
|
555
|
+
]
|
|
556
|
+
}
|
|
557
|
+
];
|
|
506
558
|
export type TaskType = "initialization" |
|
|
507
559
|
"authenticate user" |
|
|
508
560
|
"reload React" |
|
|
@@ -522,10 +574,10 @@ export class TaskArray {
|
|
|
522
574
|
this.tasks.length = 0;
|
|
523
575
|
// then clear localStorage if we have been asked to
|
|
524
576
|
if (bClearLocalStorage) {
|
|
525
|
-
if (storageAvailable(
|
|
577
|
+
if (storageAvailable()) localStorage.removeItem("Tasks");
|
|
526
578
|
}
|
|
527
579
|
// then try localStorage
|
|
528
|
-
if (storageAvailable(
|
|
580
|
+
if (storageAvailable()) {
|
|
529
581
|
let result = localStorage.getItem("Tasks");
|
|
530
582
|
if (result != null && typeof result === "string" && result !== "") {
|
|
531
583
|
// properly create Tasks and Dates from retrieved string
|
|
@@ -606,23 +658,23 @@ export class TaskArray {
|
|
|
606
658
|
}
|
|
607
659
|
#save(): void {
|
|
608
660
|
let taskArrayString: string = JSON.stringify(this);
|
|
609
|
-
if (storageAvailable(
|
|
661
|
+
if (storageAvailable()) {
|
|
610
662
|
localStorage.setItem("Tasks", taskArrayString);
|
|
611
663
|
}
|
|
612
664
|
}
|
|
613
665
|
}
|
|
614
666
|
export class Task {
|
|
615
|
-
id: number;
|
|
616
|
-
task: string;
|
|
617
|
-
start: Date;
|
|
618
|
-
startDisplay: string;
|
|
619
|
-
end: Date;
|
|
620
|
-
endDisplay: string;
|
|
621
|
-
elapsedDisplay: string;
|
|
622
|
-
expected: number;
|
|
623
|
-
status: string;
|
|
624
|
-
expanded: boolean;
|
|
625
|
-
subtasks: Task[];
|
|
667
|
+
id: number = 0;
|
|
668
|
+
task: string = "";
|
|
669
|
+
start: Date = new Date();
|
|
670
|
+
startDisplay: string = "";
|
|
671
|
+
end: Date = new Date();
|
|
672
|
+
endDisplay: string = "";
|
|
673
|
+
elapsedDisplay: string = "";
|
|
674
|
+
expected: number = 0;
|
|
675
|
+
status: string = "";
|
|
676
|
+
expanded: boolean = false;
|
|
677
|
+
subtasks: Task[] = [];
|
|
626
678
|
setEnd(endDate: Date): void {
|
|
627
679
|
this.end = endDate;
|
|
628
680
|
this.endDisplay = `${this.end.getMinutes().toString().padStart(2, "0")}:${this.end.getSeconds().toString().padStart(2, "0")}`;
|
|
@@ -640,9 +692,9 @@ export class Task {
|
|
|
640
692
|
}
|
|
641
693
|
// class corresponding to an execution of a Config - a *TenantNode* for each source tenant, each with a *TenantNode* array of target tenants
|
|
642
694
|
export class Milestone {
|
|
643
|
-
Run: number;
|
|
644
|
-
Start: Date;
|
|
645
|
-
startDisplay: string;
|
|
695
|
+
Run: number = 0;
|
|
696
|
+
Start: Date = new Date();
|
|
697
|
+
startDisplay: string = "";
|
|
646
698
|
POST: Date;
|
|
647
699
|
postDisplay: string;
|
|
648
700
|
Read: Date;
|
|
@@ -654,13 +706,13 @@ export class Milestone {
|
|
|
654
706
|
constructor(run: number) {
|
|
655
707
|
this.Run = run;
|
|
656
708
|
this.start("");
|
|
657
|
-
this.POST =
|
|
709
|
+
this.POST = new Date();
|
|
658
710
|
this.postDisplay = "";
|
|
659
|
-
this.Read =
|
|
711
|
+
this.Read = new Date();
|
|
660
712
|
this.readDisplay = "";
|
|
661
|
-
this.Write =
|
|
713
|
+
this.Write = new Date();
|
|
662
714
|
this.writeDisplay = "";
|
|
663
|
-
this.Duration =
|
|
715
|
+
this.Duration = new Date();
|
|
664
716
|
this.durationDisplay = "";
|
|
665
717
|
}
|
|
666
718
|
start(start: string): void {
|
|
@@ -683,13 +735,13 @@ export class Milestone {
|
|
|
683
735
|
}
|
|
684
736
|
}
|
|
685
737
|
export class MilestoneArray {
|
|
686
|
-
milestones: Milestone[];
|
|
738
|
+
milestones: Milestone[] = [];
|
|
687
739
|
constructor(bClearLocalStorage: boolean) {
|
|
688
740
|
this.init(bClearLocalStorage);
|
|
689
741
|
}
|
|
690
742
|
init(bClearLocalStorage: boolean): void {
|
|
691
743
|
// read from localstorage by default
|
|
692
|
-
if (storageAvailable(
|
|
744
|
+
if (storageAvailable()) {
|
|
693
745
|
let result = localStorage.getItem("syncmilestones");
|
|
694
746
|
if (result != null && typeof result === "string" && result !== "") {
|
|
695
747
|
let milestonesString: string = result;
|
|
@@ -710,7 +762,7 @@ export class MilestoneArray {
|
|
|
710
762
|
}
|
|
711
763
|
save(): void {
|
|
712
764
|
let milestonesString: string = JSON.stringify(this.milestones);
|
|
713
|
-
if (storageAvailable(
|
|
765
|
+
if (storageAvailable()) {
|
|
714
766
|
localStorage.setItem("syncmilestones", milestonesString);
|
|
715
767
|
}
|
|
716
768
|
}
|
|
@@ -743,9 +795,8 @@ export class MilestoneArray {
|
|
|
743
795
|
unstart(setMilestones: (milestones: Milestone[]) => void): void {
|
|
744
796
|
// we should always have a milestone array and a first milestone
|
|
745
797
|
if (this.milestones == null || this.milestones.length < 1) { debugger; return; }
|
|
746
|
-
let currentRun: number = Number(this.milestones[0].Run);
|
|
747
798
|
// remove first milestone from front of array
|
|
748
|
-
let removedMilestone: Milestone = this.milestones.shift();
|
|
799
|
+
let removedMilestone: Milestone | undefined = this.milestones.shift();
|
|
749
800
|
// re-define milestone array to trigger render
|
|
750
801
|
this.milestones = this.milestones.map((ms: Milestone) => {
|
|
751
802
|
let newms = new Milestone(ms.Run);
|
|
@@ -762,7 +813,7 @@ export class MilestoneArray {
|
|
|
762
813
|
return newms;
|
|
763
814
|
});
|
|
764
815
|
setMilestones(this.milestones);
|
|
765
|
-
console.log(`Unstart removed first milestone: ${removedMilestone
|
|
816
|
+
console.log(`Unstart removed first milestone: ${removedMilestone!.Run}:${removedMilestone!.Start}`);
|
|
766
817
|
}
|
|
767
818
|
post(setMilestones: (milestones: Milestone[]) => void): void {
|
|
768
819
|
// update the post value of the first milestone
|
|
@@ -782,8 +833,8 @@ export class MilestoneArray {
|
|
|
782
833
|
this.milestones[0].write("");
|
|
783
834
|
// while we have >10 complete milestones, remove the last
|
|
784
835
|
while (this.milestones.length > 10) {
|
|
785
|
-
let removed: Milestone = this.milestones.pop();
|
|
786
|
-
console.log(`Removed milestone #${removed
|
|
836
|
+
let removed: Milestone | undefined = this.milestones.pop();
|
|
837
|
+
console.log(`Removed milestone #${removed!.Run}: ${removed!.Start}`);
|
|
787
838
|
}
|
|
788
839
|
// save to localstorage
|
|
789
840
|
this.save();
|
|
@@ -809,7 +860,7 @@ export class MilestoneArray {
|
|
|
809
860
|
this.milestones = new Array();
|
|
810
861
|
}
|
|
811
862
|
else {
|
|
812
|
-
this.milestones = milestones.map((milestone:
|
|
863
|
+
this.milestones = milestones.map((milestone: any) => {
|
|
813
864
|
let ms: Milestone = new Milestone(Number(milestone.Run));
|
|
814
865
|
ms.start(milestone.Start);
|
|
815
866
|
ms.post(milestone.POST);
|
|
@@ -828,7 +879,7 @@ export class BatchArray {
|
|
|
828
879
|
pb_idle: number;
|
|
829
880
|
pb_idleMax: number;
|
|
830
881
|
pb_total: number;
|
|
831
|
-
pb_timer: NodeJS.
|
|
882
|
+
pb_timer: NodeJS.Timeout | null;
|
|
832
883
|
milestoneArray: MilestoneArray;
|
|
833
884
|
constructor(
|
|
834
885
|
config: Config | null,
|
|
@@ -857,8 +908,8 @@ export class BatchArray {
|
|
|
857
908
|
);
|
|
858
909
|
// clear localStorage if we have been asked to
|
|
859
910
|
if (bClearLocalStorage) {
|
|
860
|
-
if (storageAvailable(
|
|
861
|
-
localStorage.removeItem(config
|
|
911
|
+
if (storageAvailable()) {
|
|
912
|
+
localStorage.removeItem(config!.name);
|
|
862
913
|
this.milestoneArray.init(bClearLocalStorage);
|
|
863
914
|
}
|
|
864
915
|
}
|
|
@@ -937,7 +988,7 @@ export class BatchArray {
|
|
|
937
988
|
this.pb_timer = setInterval(() => {
|
|
938
989
|
// if signalR has finished the sync, stop the timer
|
|
939
990
|
if (this.milestoneArray.milestones[0].Write != null) {
|
|
940
|
-
clearInterval(this.pb_timer);
|
|
991
|
+
clearInterval(this.pb_timer!);
|
|
941
992
|
this.pb_timer = null;
|
|
942
993
|
this.pb_progress = 100;
|
|
943
994
|
setSyncProgress(this.pb_progress);
|
|
@@ -970,7 +1021,7 @@ export class BatchArray {
|
|
|
970
1021
|
setSyncProgress(this.pb_progress);
|
|
971
1022
|
setConfigSyncResult("sync failed to execute");
|
|
972
1023
|
this.pb_increment = 0;
|
|
973
|
-
clearInterval(this.pb_timer);
|
|
1024
|
+
clearInterval(this.pb_timer!);
|
|
974
1025
|
this.pb_timer = null;
|
|
975
1026
|
this.pb_idle = 0;
|
|
976
1027
|
this.pb_idleMax = 0;
|
|
@@ -990,25 +1041,26 @@ export class BatchArray {
|
|
|
990
1041
|
setConfigSyncResult: (result: string) => void,
|
|
991
1042
|
bClearLocalStorage: boolean
|
|
992
1043
|
): void {
|
|
1044
|
+
bClearLocalStorage = bClearLocalStorage;
|
|
993
1045
|
// we have just completed a successful POST to startSync
|
|
994
1046
|
this.milestoneArray.post(setMilestones);
|
|
995
1047
|
setConfigSyncResult("started sync, waiting for updates...");
|
|
996
1048
|
// re-initialize batch array with Configuration updated by the succcessful POST to startSync
|
|
997
1049
|
this.init(config, syncPortalGlobalState, false);
|
|
998
1050
|
// define newMessage handler that can access *this*
|
|
999
|
-
let handler = (message) => {
|
|
1051
|
+
let handler = (message: string) => {
|
|
1000
1052
|
console.log(message);
|
|
1001
1053
|
let item = JSON.parse(message);
|
|
1002
1054
|
// reset the countdown timer every time we get a message
|
|
1003
1055
|
this.pb_idle = 0;
|
|
1004
1056
|
// find the associated tenant for this SignalR message
|
|
1005
|
-
let matchingPair:
|
|
1057
|
+
let matchingPair: any | undefined = batchIdArray.find((o: any) => o.BatchId == item.TargetID);
|
|
1006
1058
|
if (matchingPair == null) {
|
|
1007
1059
|
console.log(`Batch ${item.TargetID} not found in batchIdArray.`);
|
|
1008
1060
|
debugger;
|
|
1009
1061
|
return;
|
|
1010
1062
|
}
|
|
1011
|
-
let tenantNode: TenantNode = this.tenantNodes.find((t: TenantNode) => t.tid === matchingPair.SourceId);
|
|
1063
|
+
let tenantNode: TenantNode | undefined = this.tenantNodes.find((t: TenantNode) => t.tid === matchingPair.SourceId);
|
|
1012
1064
|
if (tenantNode == null) { // null OR undefined
|
|
1013
1065
|
console.log(`Tenant ${matchingPair.SourceId} not found in BatchArray.`);
|
|
1014
1066
|
debugger;
|
|
@@ -1058,14 +1110,14 @@ export class BatchArray {
|
|
|
1058
1110
|
if (bCurrentCount) tidRegexp = /Writer\/TID:(.+)\/CurrentCount/;
|
|
1059
1111
|
if (bDeferredCount) tidRegexp = /Writer\/TID:(.+)\/DeferredCount/;
|
|
1060
1112
|
if (bRescheduledCount) tidRegexp = /Writer\/TID:(.+)\/RescheduledCount/;
|
|
1061
|
-
let matchTID = statskeys[j].match(tidRegexp);
|
|
1113
|
+
let matchTID: RegExpMatchArray | null = statskeys[j].match(tidRegexp);
|
|
1062
1114
|
if (matchTID == null) {
|
|
1063
1115
|
console.log(`tid not found in ${statskeys[j]}.`);
|
|
1064
1116
|
debugger;
|
|
1065
1117
|
return;
|
|
1066
1118
|
}
|
|
1067
1119
|
// this Writer node should exist precisely under the Reader for this SignalR message
|
|
1068
|
-
let writerNode: TenantNode = tenantNode.targets.find((t: TenantNode) => t.tid === matchTID[1]);
|
|
1120
|
+
let writerNode: TenantNode | undefined = tenantNode.targets.find((t: TenantNode) => t.tid === matchTID[1]);
|
|
1069
1121
|
if (writerNode == null) {
|
|
1070
1122
|
console.log(`Writer ${tenantNode.name} not found under Reader ${tenantNode.name}.`);
|
|
1071
1123
|
debugger;
|
|
@@ -1162,7 +1214,7 @@ export class BatchArray {
|
|
|
1162
1214
|
}
|
|
1163
1215
|
}
|
|
1164
1216
|
// start SignalR connection based on each batchId
|
|
1165
|
-
batchIdArray.map((batchPair:
|
|
1217
|
+
batchIdArray.map((batchPair: any) => {
|
|
1166
1218
|
const endpoint: string = mindlineConfig.signalREndpoint();
|
|
1167
1219
|
let endpointUrl: URL = new URL(endpoint);
|
|
1168
1220
|
endpointUrl.searchParams.append("statsId", batchPair.BatchId);
|
|
@@ -1204,20 +1256,20 @@ export class BatchArray {
|
|
|
1204
1256
|
return result;
|
|
1205
1257
|
}
|
|
1206
1258
|
// execute post to reader endpoint
|
|
1207
|
-
result = await readerPost(instance, authorizedUser
|
|
1259
|
+
result = await readerPost(instance, authorizedUser!, config!);
|
|
1208
1260
|
return result;
|
|
1209
1261
|
}
|
|
1210
1262
|
}
|
|
1211
1263
|
export class TenantNode {
|
|
1212
1264
|
expanded: boolean;
|
|
1213
|
-
status: string;
|
|
1265
|
+
status: string = "";
|
|
1214
1266
|
name: string;
|
|
1215
1267
|
tid: string;
|
|
1216
1268
|
batchId: string;
|
|
1217
|
-
total: number;
|
|
1218
|
-
read: number;
|
|
1219
|
-
written: number;
|
|
1220
|
-
deferred: number;
|
|
1269
|
+
total: number = 0;
|
|
1270
|
+
read: number = 0;
|
|
1271
|
+
written: number = 0;
|
|
1272
|
+
deferred: number =0 ;
|
|
1221
1273
|
nothingtosync: boolean;
|
|
1222
1274
|
targets: TenantNode[];
|
|
1223
1275
|
constructor(tid: string, name: string, batchId: string) {
|
|
@@ -1258,7 +1310,7 @@ export class ResourceArray {
|
|
|
1258
1310
|
init(bClearLocalStorage: boolean): void {
|
|
1259
1311
|
console.log(`Calling ResourceArray::init(bClearLocalStorage: ${bClearLocalStorage ? "true" : "false"})`);
|
|
1260
1312
|
// if we have a non-empty string value stored, read it from localStorage
|
|
1261
|
-
if (storageAvailable(
|
|
1313
|
+
if (storageAvailable()) {
|
|
1262
1314
|
let result = localStorage.getItem("ResourceArray");
|
|
1263
1315
|
if (result != null && typeof result === "string" && result !== "") {
|
|
1264
1316
|
if (bClearLocalStorage) {
|
|
@@ -1290,7 +1342,7 @@ export class ResourceArray {
|
|
|
1290
1342
|
// save resource data to localstorage
|
|
1291
1343
|
save(): void {
|
|
1292
1344
|
// if we have localStorage, save resources
|
|
1293
|
-
if (storageAvailable(
|
|
1345
|
+
if (storageAvailable()) {
|
|
1294
1346
|
let raString: string = JSON.stringify(this);
|
|
1295
1347
|
localStorage.setItem("ResourceArray", raString);
|
|
1296
1348
|
}
|
|
@@ -1320,7 +1372,7 @@ export class ActorArray {
|
|
|
1320
1372
|
init(bClearLocalStorage: boolean): void {
|
|
1321
1373
|
console.log(`Calling ResourceArray::init(bClearLocalStorage: ${bClearLocalStorage ? "true" : "false"})`);
|
|
1322
1374
|
// if we have a non-empty string value stored, read it from localStorage
|
|
1323
|
-
if (storageAvailable(
|
|
1375
|
+
if (storageAvailable()) {
|
|
1324
1376
|
let result = localStorage.getItem("RBACActors");
|
|
1325
1377
|
if (result != null && typeof result === "string" && result !== "") {
|
|
1326
1378
|
if (bClearLocalStorage) {
|
|
@@ -1353,7 +1405,7 @@ export class ActorNode {
|
|
|
1353
1405
|
actors: ActorNode[];
|
|
1354
1406
|
constructor(type: string, actor: string, resource: string, role: string, updatedby: string, updatedon: string) {
|
|
1355
1407
|
this.type = type;
|
|
1356
|
-
this.actor =
|
|
1408
|
+
this.actor = actor;
|
|
1357
1409
|
this.resource = resource;
|
|
1358
1410
|
this.role = role;
|
|
1359
1411
|
this.updatedby = updatedby;
|
|
@@ -1364,6 +1416,7 @@ export class ActorNode {
|
|
|
1364
1416
|
// ======================= Azure AD Graph API ===============================
|
|
1365
1417
|
// helper functions
|
|
1366
1418
|
function getGraphAPIScope(user: User): string {
|
|
1419
|
+
user = user;
|
|
1367
1420
|
return "Group.Read.All User.Read.All openid profile offline_access User.Read Contacts.Read CrossTenantInformation.ReadBasic.All";
|
|
1368
1421
|
}
|
|
1369
1422
|
// TODO: this is where you want to trigger a re-authentication if token expires
|
|
@@ -1393,7 +1446,7 @@ async function graphDefineHeaders(
|
|
|
1393
1446
|
try {
|
|
1394
1447
|
let accounts: AccountInfo[] = instance.getAllAccounts();
|
|
1395
1448
|
let homeAccountId = user.oid + "." + user.tid;
|
|
1396
|
-
let account: AccountInfo = null;
|
|
1449
|
+
let account: AccountInfo | undefined | null = null;
|
|
1397
1450
|
for (let i: number = 0; i < accounts.length; i++) {
|
|
1398
1451
|
if (accounts[i].homeAccountId == homeAccountId) {
|
|
1399
1452
|
account = accounts[i];
|
|
@@ -1401,7 +1454,7 @@ async function graphDefineHeaders(
|
|
|
1401
1454
|
}
|
|
1402
1455
|
let response: AuthenticationResult = await instance.acquireTokenSilent({
|
|
1403
1456
|
scopes: [graphAPIScope],
|
|
1404
|
-
account: account
|
|
1457
|
+
account: account!
|
|
1405
1458
|
});
|
|
1406
1459
|
user.graphAccessToken = response.accessToken; // cache access token
|
|
1407
1460
|
console.log("Front end token graph acquired silently: " + user.graphAccessToken.slice(0, 20));
|
|
@@ -1412,7 +1465,7 @@ async function graphDefineHeaders(
|
|
|
1412
1465
|
// fallback to redirect if silent acquisition fails
|
|
1413
1466
|
let accounts: AccountInfo[] = instance.getAllAccounts();
|
|
1414
1467
|
let homeAccountId = user.oid + "." + user.tid;
|
|
1415
|
-
let account: AccountInfo = null;
|
|
1468
|
+
let account: AccountInfo | null = null;
|
|
1416
1469
|
for (let i: number = 0; i < accounts.length; i++) {
|
|
1417
1470
|
if (accounts[i].homeAccountId == homeAccountId) {
|
|
1418
1471
|
account = accounts[i];
|
|
@@ -1421,7 +1474,7 @@ async function graphDefineHeaders(
|
|
|
1421
1474
|
// assumption: this redirect will trigger login flow callbacks in program.cs
|
|
1422
1475
|
instance.acquireTokenRedirect({
|
|
1423
1476
|
scopes: [graphAPIScope],
|
|
1424
|
-
account: account
|
|
1477
|
+
account: account!
|
|
1425
1478
|
});
|
|
1426
1479
|
}
|
|
1427
1480
|
catch (error: any) {
|
|
@@ -1456,7 +1509,7 @@ export async function groupsGet(instance: IPublicClientApplication, user: User |
|
|
|
1456
1509
|
return { groups: [], error: `Exception: ${error}` };
|
|
1457
1510
|
}
|
|
1458
1511
|
}
|
|
1459
|
-
export async function oauth2PermissionGrantsGet(options: RequestInit, user: User, spid: string, oid: string): Promise<{ grants: string, id: string, error: string }> {
|
|
1512
|
+
export async function oauth2PermissionGrantsGet(options: RequestInit, user: User, spid: string, oid: string): Promise<{ grants: string|null, id: string|null, error: string }> {
|
|
1460
1513
|
try {
|
|
1461
1514
|
// make /oauth2PermissionGrants endpoint call
|
|
1462
1515
|
let spurl: string = getGraphEndpoint(user.authority) + graphConfig.graphOauth2PermissionGrantsPredicate;
|
|
@@ -1492,6 +1545,7 @@ export async function oauth2PermissionGrantsSet(instance: IPublicClientApplicati
|
|
|
1492
1545
|
const headers = await graphDefineHeaders(instance, loggedInUser);
|
|
1493
1546
|
let options: RequestInit = { method: "PATCH", headers: headers, body: scopesBody };
|
|
1494
1547
|
let response = await fetch(grantsurl, options);
|
|
1548
|
+
let data = await response.json();
|
|
1495
1549
|
if (response.status == 204 && response.statusText == "No Content") {
|
|
1496
1550
|
return true;
|
|
1497
1551
|
}
|
|
@@ -1740,6 +1794,7 @@ export async function tenantRelationshipsGetByDomain(loggedInUser: User, tenant:
|
|
|
1740
1794
|
}
|
|
1741
1795
|
//tenantRelationshipsGetById - query AAD for associated company name and domain
|
|
1742
1796
|
export async function tenantRelationshipsGetById(loggedInUser: User, tenant: Tenant, ii: InitInfo, instance: IPublicClientApplication, debug: boolean): Promise<boolean> {
|
|
1797
|
+
ii = ii;
|
|
1743
1798
|
console.log("**** tenantRelationshipsGetById");
|
|
1744
1799
|
if (debug) debugger;
|
|
1745
1800
|
// if needed, retrieve and cache access token
|
|
@@ -1846,7 +1901,7 @@ export async function tenantUnauthenticatedLookup(tenant: Tenant, debug: boolean
|
|
|
1846
1901
|
}
|
|
1847
1902
|
return false; // failed, no need for UX to re-render
|
|
1848
1903
|
}
|
|
1849
|
-
export async function userDelegatedScopesGet(instance: IPublicClientApplication, loggedInUser: User, tenant: Tenant): Promise<{ scopes: string, id: string, error: string }> {
|
|
1904
|
+
export async function userDelegatedScopesGet(instance: IPublicClientApplication, loggedInUser: User, tenant: Tenant): Promise<{ scopes: string|null, id: string|null, error: string }> {
|
|
1850
1905
|
// need a logged in user and valid tenant to query graph
|
|
1851
1906
|
if (loggedInUser == null || loggedInUser.spacode == "" || tenant == null) {
|
|
1852
1907
|
debugger;
|
|
@@ -1893,9 +1948,9 @@ export async function userDelegatedScopesRemove(instance: IPublicClientApplicati
|
|
|
1893
1948
|
return false;
|
|
1894
1949
|
}
|
|
1895
1950
|
// remove passed scope (case sensitive)
|
|
1896
|
-
scopes = scopes
|
|
1951
|
+
scopes = scopes!.replace(scope, "");
|
|
1897
1952
|
// set updated oauth2permissions
|
|
1898
|
-
let removed: boolean = await oauth2PermissionGrantsSet(instance, loggedInUser, id
|
|
1953
|
+
let removed: boolean = await oauth2PermissionGrantsSet(instance, loggedInUser, id!, scopes);
|
|
1899
1954
|
if (!removed) {
|
|
1900
1955
|
debugger;
|
|
1901
1956
|
console.log(`userDelegatedScopesRemove: cannot set oauth2PermissionGrants for ${loggedInUser.mail}: ${error}`);
|
|
@@ -1995,7 +2050,7 @@ export async function configsRefresh(instance: IPublicClientApplication, authori
|
|
|
1995
2050
|
let result: APIResult = new APIResult();
|
|
1996
2051
|
if (debug) debugger;
|
|
1997
2052
|
try {
|
|
1998
|
-
let workspace: Workspace = ii.ws.find((w) => w.id === workspaceId);
|
|
2053
|
+
let workspace: Workspace | undefined = ii.ws.find((w) => w.id === workspaceId);
|
|
1999
2054
|
if (workspace != null) {
|
|
2000
2055
|
// clear Config associations as we are about to reset
|
|
2001
2056
|
workspace.associatedConfigs.length = 0;
|
|
@@ -2082,9 +2137,9 @@ export async function workspaceEdit(instance: IPublicClientApplication, authoriz
|
|
|
2082
2137
|
}
|
|
2083
2138
|
// retrieve Workspace(s), User(s), Tenant(s), Config(s) given newly logged in user
|
|
2084
2139
|
function processReturnedAdmins(workspace: Workspace, ii: InitInfo, returnedAdmins: Array<Object>, adminSelectedId: string) {
|
|
2085
|
-
returnedAdmins.map((item) => {
|
|
2140
|
+
returnedAdmins.map((item: any) => {
|
|
2086
2141
|
// are we already tracking this user?
|
|
2087
|
-
let user: User | null = null;
|
|
2142
|
+
let user: User | null | undefined = null;
|
|
2088
2143
|
let usIndex = ii.us.findIndex((u) => (u.oid === item.userId || u.oid === item.email));
|
|
2089
2144
|
if (usIndex === -1) {
|
|
2090
2145
|
// start tracking
|
|
@@ -2109,12 +2164,12 @@ function processReturnedAdmins(workspace: Workspace, ii: InitInfo, returnedAdmin
|
|
|
2109
2164
|
user = ii.us.at(usIndex);
|
|
2110
2165
|
}
|
|
2111
2166
|
// restore selection
|
|
2112
|
-
user
|
|
2167
|
+
user!.sel = (adminSelectedId === item.userId);
|
|
2113
2168
|
// refresh all the data available from the server
|
|
2114
|
-
user
|
|
2115
|
-
user
|
|
2116
|
-
user
|
|
2117
|
-
user
|
|
2169
|
+
user!.oid = item.userId ? item.userId : item.email;
|
|
2170
|
+
user!.name = item.firstName ?? user!.name;
|
|
2171
|
+
user!.mail = item.email;
|
|
2172
|
+
user!.tid = item.tenantId;
|
|
2118
2173
|
// *try* to set authority/companyName/companyDomain from tenant returned in previous call processReturnedTenants (it may not be there)
|
|
2119
2174
|
// ASSUMPTION: in terms of setting authority, user either comes from
|
|
2120
2175
|
// 1. .NET session, in which case user has an authority from the token
|
|
@@ -2122,22 +2177,22 @@ function processReturnedAdmins(workspace: Workspace, ii: InitInfo, returnedAdmin
|
|
|
2122
2177
|
// a. associated tenant with authority exists for this user (i.e. workspace owner has called POST init/configuration and created Admin and Tenant at same time)
|
|
2123
2178
|
// b. user has never logged in (i.e. workspace owner has invited an incomplete admin to the workspace and there is no corresponding tenant)
|
|
2124
2179
|
// i. this means that we *may* not have an authority stored for this user
|
|
2125
|
-
let tenant: Tenant | undefined = ii.ts.find((t) => (t.tid === user
|
|
2180
|
+
let tenant: Tenant | undefined = ii.ts.find((t) => (t.tid === user!.tid));
|
|
2126
2181
|
if (tenant != undefined) {
|
|
2127
|
-
user
|
|
2128
|
-
user
|
|
2129
|
-
user
|
|
2182
|
+
user!.authority = tenant.authority;
|
|
2183
|
+
user!.companyName = tenant.name;
|
|
2184
|
+
user!.companyDomain = tenant.domain;
|
|
2130
2185
|
}
|
|
2131
2186
|
// ensure this workspace tracks this user
|
|
2132
|
-
let idx = workspace.associatedUsers.findIndex((u) => u === user
|
|
2133
|
-
if (idx == -1) workspace.associatedUsers.push(user
|
|
2187
|
+
let idx = workspace.associatedUsers.findIndex((u) => u === user!.oid);
|
|
2188
|
+
if (idx == -1) workspace.associatedUsers.push(user!.oid);
|
|
2134
2189
|
});
|
|
2135
2190
|
ii.save();
|
|
2136
2191
|
}
|
|
2137
2192
|
function processReturnedTenants(workspace: Workspace, ii: InitInfo, returnedTenants: Array<Object>, tenantSelectedId: string) {
|
|
2138
|
-
returnedTenants.map((item) => {
|
|
2193
|
+
returnedTenants.map((item: any) => {
|
|
2139
2194
|
// are we already tracking this tenant?
|
|
2140
|
-
let tenant: Tenant | null = null;
|
|
2195
|
+
let tenant: Tenant | null | undefined = null;
|
|
2141
2196
|
let tsIndex = ii.ts.findIndex((t) => t.tid === item.tenantId);
|
|
2142
2197
|
if (tsIndex === -1) {
|
|
2143
2198
|
// start tracking
|
|
@@ -2161,17 +2216,17 @@ function processReturnedTenants(workspace: Workspace, ii: InitInfo, returnedTena
|
|
|
2161
2216
|
tenant = ii.ts.at(tsIndex);
|
|
2162
2217
|
}
|
|
2163
2218
|
// restore selection
|
|
2164
|
-
tenant
|
|
2219
|
+
tenant!.sel = (tenantSelectedId === item.tenantId);
|
|
2165
2220
|
// refresh all the data available from the server
|
|
2166
|
-
tenant
|
|
2167
|
-
tenant
|
|
2168
|
-
tenant
|
|
2169
|
-
tenant
|
|
2221
|
+
tenant!.tid = item.tenantId;
|
|
2222
|
+
tenant!.name = item.name;
|
|
2223
|
+
tenant!.domain = item.domain;
|
|
2224
|
+
tenant!.tenantType = item.type.toLowerCase(); // should now be strings
|
|
2170
2225
|
|
|
2171
2226
|
// canonicalize authority when getting it from config backend
|
|
2172
2227
|
const regex = /^(https:\/\/login.microsoftonline.(?:us|com)\/)organizations\/v2.0$/;
|
|
2173
2228
|
const regexMatch = item.authority.match(regex);
|
|
2174
|
-
tenant
|
|
2229
|
+
tenant!.authority = regexMatch ? regexMatch[1] : item.authority;
|
|
2175
2230
|
|
|
2176
2231
|
// ensure this workspace tracks this tenant
|
|
2177
2232
|
let idx = workspace.associatedTenants.findIndex((t) => t === item.tenantId);
|
|
@@ -2181,9 +2236,9 @@ function processReturnedTenants(workspace: Workspace, ii: InitInfo, returnedTena
|
|
|
2181
2236
|
}
|
|
2182
2237
|
function processReturnedConfigs(workspace: Workspace, ii: InitInfo, returnedConfigs: Array<Object>, configSelectedId: string) {
|
|
2183
2238
|
// process returned configs
|
|
2184
|
-
returnedConfigs.map((item) => {
|
|
2239
|
+
returnedConfigs.map((item: any) => {
|
|
2185
2240
|
// are we already tracking this config?
|
|
2186
|
-
let config: Config | null = null;
|
|
2241
|
+
let config: Config | null | undefined = null;
|
|
2187
2242
|
let csIndex = ii.cs.findIndex((c) => c.id === item.id);
|
|
2188
2243
|
if (csIndex === -1) {
|
|
2189
2244
|
// start tracking
|
|
@@ -2207,7 +2262,7 @@ function processReturnedConfigs(workspace: Workspace, ii: InitInfo, returnedConf
|
|
|
2207
2262
|
config = ii.cs.at(csIndex);
|
|
2208
2263
|
}
|
|
2209
2264
|
// restore selection
|
|
2210
|
-
config
|
|
2265
|
+
config!.sel = (configSelectedId === item.id);
|
|
2211
2266
|
// refresh all the data available from the server
|
|
2212
2267
|
config!.id = item.id;
|
|
2213
2268
|
config!.workspaceId = item.workspaceId;
|
|
@@ -2216,7 +2271,7 @@ function processReturnedConfigs(workspace: Workspace, ii: InitInfo, returnedConf
|
|
|
2216
2271
|
config!.isEnabled = item.isEnabled;
|
|
2217
2272
|
// create TenantConfigInfo array
|
|
2218
2273
|
config!.tenants.length = 0;
|
|
2219
|
-
item.tenants.map((tci) => {
|
|
2274
|
+
item.tenants.map((tci: any) => {
|
|
2220
2275
|
let tenantConfigInfo = new TenantConfigInfo();
|
|
2221
2276
|
tenantConfigInfo.tid = tci.tenantId;
|
|
2222
2277
|
tenantConfigInfo.sourceGroupId = tci.sourceGroupId ?? "";
|
|
@@ -2243,9 +2298,9 @@ async function workspaceInfoGet(instance: IPublicClientApplication, user: User,
|
|
|
2243
2298
|
try {
|
|
2244
2299
|
result = await workspacesGet(instance, user, debug);
|
|
2245
2300
|
if (result.result) {
|
|
2246
|
-
for (let o of result.array!) {
|
|
2301
|
+
for (let o of result.array! as Workspace[]) {
|
|
2247
2302
|
// are we already tracking this workspace?
|
|
2248
|
-
let workspace: Workspace = null;
|
|
2303
|
+
let workspace: Workspace | null | undefined = null;
|
|
2249
2304
|
let wsIndex = ii.ws.findIndex((w) => w.id === o.id);
|
|
2250
2305
|
if (wsIndex === -1) {
|
|
2251
2306
|
// start tracking
|
|
@@ -2265,47 +2320,47 @@ async function workspaceInfoGet(instance: IPublicClientApplication, user: User,
|
|
|
2265
2320
|
}
|
|
2266
2321
|
// preserve selected admin, tenant, and config
|
|
2267
2322
|
let adminSelectedId: string = "";
|
|
2268
|
-
for (let oid of workspace
|
|
2323
|
+
for (let oid of workspace!.associatedUsers) {
|
|
2269
2324
|
let user = ii.us.find((u: User) => u.oid === oid);
|
|
2270
2325
|
if (user != null && user.sel) {
|
|
2271
2326
|
adminSelectedId = user.oid;
|
|
2272
2327
|
}
|
|
2273
2328
|
}
|
|
2274
2329
|
let tenantSelectedId: string = "";
|
|
2275
|
-
for (let tid of workspace
|
|
2330
|
+
for (let tid of workspace!.associatedTenants) {
|
|
2276
2331
|
let tenant = ii.ts.find((t: Tenant) => t.tid === tid);
|
|
2277
2332
|
if (tenant != null && tenant.sel) {
|
|
2278
2333
|
tenantSelectedId = tenant.tid;
|
|
2279
2334
|
}
|
|
2280
2335
|
}
|
|
2281
2336
|
let configSelectedId: string = "";
|
|
2282
|
-
for (let cid of workspace
|
|
2337
|
+
for (let cid of workspace!.associatedConfigs) {
|
|
2283
2338
|
let config = ii.cs.find((c: Config) => c.id === cid);
|
|
2284
2339
|
if (config != null && config.sel) {
|
|
2285
2340
|
configSelectedId = config.id;
|
|
2286
2341
|
}
|
|
2287
2342
|
}
|
|
2288
2343
|
// clear associations as we are about to reset
|
|
2289
|
-
workspace
|
|
2290
|
-
workspace
|
|
2291
|
-
workspace
|
|
2344
|
+
workspace!.associatedUsers.length = 0;
|
|
2345
|
+
workspace!.associatedTenants.length = 0;
|
|
2346
|
+
workspace!.associatedConfigs.length = 0;
|
|
2292
2347
|
// set id and name based on returned data
|
|
2293
|
-
workspace
|
|
2294
|
-
workspace
|
|
2295
|
-
workspace
|
|
2348
|
+
workspace!.id = o.id;
|
|
2349
|
+
workspace!.name = o.name;
|
|
2350
|
+
workspace!.ownerid = o.ownerid;
|
|
2296
2351
|
// parallel GET admins, tenants, configs associated with this workspace
|
|
2297
|
-
let adminsPromise: Promise<APIResult> = adminsGet(instance, user, workspace
|
|
2298
|
-
let tenantsPromise: Promise<APIResult> = tenantsGet(instance, user, workspace
|
|
2299
|
-
let configsPromise: Promise<APIResult> = configsGet(instance, user, workspace
|
|
2352
|
+
let adminsPromise: Promise<APIResult> = adminsGet(instance, user, workspace!.id, debug);
|
|
2353
|
+
let tenantsPromise: Promise<APIResult> = tenantsGet(instance, user, workspace!.id, debug);
|
|
2354
|
+
let configsPromise: Promise<APIResult> = configsGet(instance, user, workspace!.id, debug);
|
|
2300
2355
|
// wait for all to finish, return on any failure
|
|
2301
2356
|
let [adminsResult, tenantsResult, configsResult] = await Promise.all([adminsPromise, tenantsPromise, configsPromise]);
|
|
2302
2357
|
if (!adminsResult.result) return adminsResult;
|
|
2303
2358
|
if (!tenantsResult.result) return tenantsResult;
|
|
2304
2359
|
if (!configsResult.result) return configsResult;
|
|
2305
2360
|
// process returned workspace components (tenants first as they have the authorities that admins depend on)
|
|
2306
|
-
processReturnedTenants(workspace
|
|
2307
|
-
processReturnedAdmins(workspace
|
|
2308
|
-
processReturnedConfigs(workspace
|
|
2361
|
+
processReturnedTenants(workspace!, ii, tenantsResult.array!, tenantSelectedId);
|
|
2362
|
+
processReturnedAdmins(workspace!, ii, adminsResult.array!, adminSelectedId);
|
|
2363
|
+
processReturnedConfigs(workspace!, ii, configsResult.array!, configSelectedId);
|
|
2309
2364
|
// tag components with workspaceIDs
|
|
2310
2365
|
ii.tagWithWorkspaces();
|
|
2311
2366
|
}
|
|
@@ -2330,7 +2385,7 @@ export async function getPowerBIAccessToken(
|
|
|
2330
2385
|
try {
|
|
2331
2386
|
let accounts: AccountInfo[] = instance.getAllAccounts();
|
|
2332
2387
|
let homeAccountId = user.oid + "." + user.tid;
|
|
2333
|
-
let account: AccountInfo = null;
|
|
2388
|
+
let account: AccountInfo | null = null;
|
|
2334
2389
|
for (let i: number = 0; i < accounts.length; i++) {
|
|
2335
2390
|
if (accounts[i].homeAccountId == homeAccountId) {
|
|
2336
2391
|
account = accounts[i];
|
|
@@ -2342,7 +2397,7 @@ export async function getPowerBIAccessToken(
|
|
|
2342
2397
|
"https://analysis.windows.net/powerbi/api/Report.ReadWrite.All",
|
|
2343
2398
|
"https://analysis.windows.net/powerbi/api/Workspace.ReadWrite.All"
|
|
2344
2399
|
],
|
|
2345
|
-
account: account
|
|
2400
|
+
account: account!
|
|
2346
2401
|
});
|
|
2347
2402
|
accesstoken = response.accessToken; // cache access token
|
|
2348
2403
|
console.log("PowerBI token acquired silently: " + accesstoken.slice(0, 20));
|
|
@@ -2366,7 +2421,7 @@ async function azureDefineHeaders(
|
|
|
2366
2421
|
try {
|
|
2367
2422
|
let accounts: AccountInfo[] = instance.getAllAccounts();
|
|
2368
2423
|
let homeAccountId = user.oid + "." + user.tid;
|
|
2369
|
-
let account: AccountInfo = null;
|
|
2424
|
+
let account: AccountInfo | null = null;
|
|
2370
2425
|
for (let i: number = 0; i < accounts.length; i++) {
|
|
2371
2426
|
if (accounts[i].homeAccountId == homeAccountId) {
|
|
2372
2427
|
account = accounts[i];
|
|
@@ -2374,7 +2429,7 @@ async function azureDefineHeaders(
|
|
|
2374
2429
|
}
|
|
2375
2430
|
let response: AuthenticationResult = await instance.acquireTokenSilent({
|
|
2376
2431
|
scopes: ["https://management.azure.com/user_impersonation"],
|
|
2377
|
-
account: account
|
|
2432
|
+
account: account!
|
|
2378
2433
|
});
|
|
2379
2434
|
user.azureAccessToken = response.accessToken; // cache access token
|
|
2380
2435
|
console.log("Front end token acquired silently: " + user.azureAccessToken.slice(0, 20));
|
|
@@ -2385,7 +2440,7 @@ async function azureDefineHeaders(
|
|
|
2385
2440
|
// fallback to redirect if silent acquisition fails
|
|
2386
2441
|
let accounts: AccountInfo[] = instance.getAllAccounts();
|
|
2387
2442
|
let homeAccountId = user.oid + "." + user.tid;
|
|
2388
|
-
let account: AccountInfo = null;
|
|
2443
|
+
let account: AccountInfo | null = null;
|
|
2389
2444
|
for (let i: number = 0; i < accounts.length; i++) {
|
|
2390
2445
|
if (accounts[i].homeAccountId == homeAccountId) {
|
|
2391
2446
|
account = accounts[i];
|
|
@@ -2393,7 +2448,7 @@ async function azureDefineHeaders(
|
|
|
2393
2448
|
}
|
|
2394
2449
|
instance.acquireTokenRedirect({
|
|
2395
2450
|
scopes: ["https://management.azure.com/user_impersonation"],
|
|
2396
|
-
account: account
|
|
2451
|
+
account: account!
|
|
2397
2452
|
});
|
|
2398
2453
|
}
|
|
2399
2454
|
catch (error: any) {
|
|
@@ -2420,7 +2475,8 @@ export async function canListRootAssignments(instance: IPublicClientApplication,
|
|
|
2420
2475
|
listrootassignmentsEndpoint += "'";
|
|
2421
2476
|
let response = await fetch(listrootassignmentsEndpoint, options);
|
|
2422
2477
|
if (response.status == 200) {
|
|
2423
|
-
let data = await response.json();
|
|
2478
|
+
let data: any = await response.json();
|
|
2479
|
+
data = data;
|
|
2424
2480
|
debugger;
|
|
2425
2481
|
console.log("Successful call to Azure Resource Graph list root assignments");
|
|
2426
2482
|
}
|
|
@@ -2479,19 +2535,20 @@ async function readResources(instance: IPublicClientApplication, user: User): Pr
|
|
|
2479
2535
|
let response = await fetch(listrootassignmentsEndpoint, options);
|
|
2480
2536
|
if (response.status == 200) {
|
|
2481
2537
|
let data = await response.json();
|
|
2538
|
+
data = data;
|
|
2482
2539
|
debugger;
|
|
2483
2540
|
console.log("Successful call to Azure Resource Graph list root assignments");
|
|
2484
2541
|
}
|
|
2485
2542
|
else {
|
|
2486
2543
|
console.log(await processErrors(response));
|
|
2487
|
-
return
|
|
2544
|
+
return resources;
|
|
2488
2545
|
}
|
|
2489
2546
|
}
|
|
2490
2547
|
catch (error: any) {
|
|
2491
2548
|
console.log(error);
|
|
2492
|
-
return
|
|
2549
|
+
return resources;
|
|
2493
2550
|
}
|
|
2494
|
-
return
|
|
2551
|
+
return resources;
|
|
2495
2552
|
}
|
|
2496
2553
|
|
|
2497
2554
|
//hybridspa.ts - calls to Mindline Config API
|
|
@@ -2514,7 +2571,6 @@ async function mindlineDefineHeaders(
|
|
|
2514
2571
|
instance: IPublicClientApplication,
|
|
2515
2572
|
user: User
|
|
2516
2573
|
): Promise<Headers> {
|
|
2517
|
-
debugger;
|
|
2518
2574
|
const headers = new Headers();
|
|
2519
2575
|
headers.append("Content-Type", "application/json");
|
|
2520
2576
|
headers.append("accept", "*/*");
|
|
@@ -2523,7 +2579,7 @@ async function mindlineDefineHeaders(
|
|
|
2523
2579
|
try {
|
|
2524
2580
|
let accounts: AccountInfo[] = instance.getAllAccounts();
|
|
2525
2581
|
let homeAccountId = user.oid + "." + user.tid;
|
|
2526
|
-
let account: AccountInfo = null;
|
|
2582
|
+
let account: AccountInfo | null = null;
|
|
2527
2583
|
for (let i: number = 0; i < accounts.length; i++) {
|
|
2528
2584
|
if (accounts[i].homeAccountId == homeAccountId) {
|
|
2529
2585
|
account = accounts[i];
|
|
@@ -2531,7 +2587,7 @@ async function mindlineDefineHeaders(
|
|
|
2531
2587
|
}
|
|
2532
2588
|
let response: AuthenticationResult = await instance.acquireTokenSilent({
|
|
2533
2589
|
scopes: [apiScope],
|
|
2534
|
-
account: account
|
|
2590
|
+
account: account!
|
|
2535
2591
|
});
|
|
2536
2592
|
user.mindlineAccessToken = response.accessToken; // cache access token
|
|
2537
2593
|
console.log("Front end mindline token acquired silently: " + user.mindlineAccessToken.slice(0, 20));
|
|
@@ -2542,7 +2598,7 @@ async function mindlineDefineHeaders(
|
|
|
2542
2598
|
// fallback to redirect if silent acquisition fails
|
|
2543
2599
|
let accounts: AccountInfo[] = instance.getAllAccounts();
|
|
2544
2600
|
let homeAccountId = user.oid + "." + user.tid;
|
|
2545
|
-
let account: AccountInfo = null;
|
|
2601
|
+
let account: AccountInfo | null = null;
|
|
2546
2602
|
for (let i: number = 0; i < accounts.length; i++) {
|
|
2547
2603
|
if (accounts[i].homeAccountId == homeAccountId) {
|
|
2548
2604
|
account = accounts[i];
|
|
@@ -2551,7 +2607,7 @@ async function mindlineDefineHeaders(
|
|
|
2551
2607
|
// assumption: this redirect will trigger login flow callbacks in program.cs
|
|
2552
2608
|
instance.acquireTokenRedirect({
|
|
2553
2609
|
scopes: [apiScope],
|
|
2554
|
-
account: account
|
|
2610
|
+
account: account!
|
|
2555
2611
|
});
|
|
2556
2612
|
}
|
|
2557
2613
|
catch (error: any) {
|
|
@@ -2664,7 +2720,7 @@ export async function adminsGet(
|
|
|
2664
2720
|
if (returnedArray != null) {
|
|
2665
2721
|
result.array = returnedArray;
|
|
2666
2722
|
let initialValue: string = "";
|
|
2667
|
-
console.log(`Successful GET from /admins: ${result.array.reduce((acc, curr) => acc + curr.email + " ", initialValue)}`);
|
|
2723
|
+
console.log(`Successful GET from /admins: ${result.array.reduce((acc, curr: any) => acc + curr.email + " ", initialValue)}`);
|
|
2668
2724
|
return result;
|
|
2669
2725
|
}
|
|
2670
2726
|
else {
|
|
@@ -2830,6 +2886,7 @@ export async function configDelete(
|
|
|
2830
2886
|
workspaceId: string,
|
|
2831
2887
|
debug: boolean
|
|
2832
2888
|
): Promise<APIResult> {
|
|
2889
|
+
debug = debug;
|
|
2833
2890
|
let result: APIResult = new APIResult();
|
|
2834
2891
|
if (config.id === "" || workspaceId == "") {
|
|
2835
2892
|
result.result = false;
|
|
@@ -3100,7 +3157,7 @@ export async function configsGet(
|
|
|
3100
3157
|
if (returnedArray != null) {
|
|
3101
3158
|
result.array = returnedArray;
|
|
3102
3159
|
let initialValue: string = "";
|
|
3103
|
-
console.log(`Successful GET from /configurations: ${result.array.reduce((acc, curr) => acc + curr.name + " ", initialValue)}`);
|
|
3160
|
+
console.log(`Successful GET from /configurations: ${result.array.reduce((acc, curr: any) => acc + curr.name + " ", initialValue)}`);
|
|
3104
3161
|
return result;
|
|
3105
3162
|
}
|
|
3106
3163
|
else {
|
|
@@ -3192,6 +3249,7 @@ export async function tenantDelete(
|
|
|
3192
3249
|
workspaceId: string,
|
|
3193
3250
|
debug: boolean
|
|
3194
3251
|
): Promise<APIResult> {
|
|
3252
|
+
debug = debug;
|
|
3195
3253
|
let result: APIResult = new APIResult();
|
|
3196
3254
|
// we expect valid tid amd workspaceId
|
|
3197
3255
|
if (tenant.tid === "" || workspaceId === "") {
|
|
@@ -3265,7 +3323,7 @@ export async function tenantsGet(
|
|
|
3265
3323
|
if (returnedArray != null) {
|
|
3266
3324
|
result.array = returnedArray;
|
|
3267
3325
|
let initialValue: string = "";
|
|
3268
|
-
console.log(`Successful GET from /tenants: ${result.array.reduce((acc, curr) => acc + curr.domain + " ", initialValue)}`);
|
|
3326
|
+
console.log(`Successful GET from /tenants: ${result.array.reduce((acc, curr: any) => acc + curr.domain + " ", initialValue)}`);
|
|
3269
3327
|
return result;
|
|
3270
3328
|
}
|
|
3271
3329
|
else {
|
|
@@ -3421,7 +3479,7 @@ export async function workspacesGet(
|
|
|
3421
3479
|
if (returnedArray != null) {
|
|
3422
3480
|
result.array = returnedArray;
|
|
3423
3481
|
let initialValue: string = "";
|
|
3424
|
-
console.log(`Successful GET from /workspaces: ${result.array.reduce((acc, curr) => acc + curr.name + " ", initialValue)}`);
|
|
3482
|
+
console.log(`Successful GET from /workspaces: ${result.array.reduce((acc, curr: any) => acc + curr.name + " ", initialValue)}`);
|
|
3425
3483
|
return result;
|
|
3426
3484
|
}
|
|
3427
3485
|
else {
|