@mindline/sync 1.0.88 → 1.0.90

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/index.ts CHANGED
@@ -14,6 +14,7 @@ import syncmilestones from './syncmilestones';
14
14
  import resources from './resources';
15
15
  import actors from './actors';
16
16
  import { log } from "console";
17
+
17
18
  const FILTER_FIELD = "workspaceIDs";
18
19
  // called by unit tests
19
20
  export function sum(a: number, b: number): number {
@@ -2491,4 +2492,1011 @@ async function readResources(instance: IPublicClientApplication, user: User): Pr
2491
2492
  return false;
2492
2493
  }
2493
2494
  return true;
2495
+ }
2496
+
2497
+ //hybridspa.ts - calls to Mindline Config API
2498
+
2499
+ // helper functions
2500
+ function getAPIScope(user: User): string {
2501
+ let apiAppID: string = "8d95d21c-c378-4bb0-9f52-88c30d271e7a";
2502
+ let authority: string = user.authority.toLowerCase();
2503
+ if (authority.startsWith("https://login.microsoftonline.com/"))
2504
+ apiAppID = "8d95d21c-c378-4bb0-9f52-88c30d271e7a";
2505
+ else if (authority.startsWith("https://login.microsoftonline.us/"))
2506
+ apiAppID = "48da942e-ea3d-49e4-a054-81649012f8f2";
2507
+ else if (authority.startsWith("https://login.partner.microsoftonline.cn/"))
2508
+ apiAppID = "c91d32e4-dcc5-4d77-826a-16e93ffce666";
2509
+ let apiScope: string = `api://${apiAppID}/Config.Write`;
2510
+ return apiScope;
2511
+ }
2512
+ // TODO: this is where you want to trigger a re-authentication if token expires
2513
+ async function mindlineDefineHeaders(
2514
+ instance: IPublicClientApplication,
2515
+ user: User
2516
+ ): Promise<Headers> {
2517
+ const headers = new Headers();
2518
+ headers.append("Content-Type", "application/json");
2519
+ headers.append("accept", "*/*");
2520
+ // always call acquireTokenSilent, handling expired tokens on exception
2521
+ const apiScope: string = getAPIScope(user);
2522
+ try {
2523
+ let accounts: AccountInfo[] = instance.getAllAccounts();
2524
+ let homeAccountId = user.oid + "." + user.tid;
2525
+ let account: AccountInfo = null;
2526
+ for (let i: number = 0; i < accounts.length; i++) {
2527
+ if (accounts[i].homeAccountId == homeAccountId) {
2528
+ account = accounts[i];
2529
+ }
2530
+ }
2531
+ let response: AuthenticationResult = await instance.acquireTokenSilent({
2532
+ scopes: [apiScope],
2533
+ account: account
2534
+ });
2535
+ user.mindlineAccessToken = response.accessToken; // cache access token
2536
+ console.log("Front end mindline token acquired silently: " + user.mindlineAccessToken.slice(0, 20));
2537
+ }
2538
+ catch (error: any) {
2539
+ try {
2540
+ console.log("Front end mindline token silent acquisition failure, triggering redirect: " + error);
2541
+ // fallback to redirect if silent acquisition fails
2542
+ let accounts: AccountInfo[] = instance.getAllAccounts();
2543
+ let homeAccountId = user.oid + "." + user.tid;
2544
+ let account: AccountInfo = null;
2545
+ for (let i: number = 0; i < accounts.length; i++) {
2546
+ if (accounts[i].homeAccountId == homeAccountId) {
2547
+ account = accounts[i];
2548
+ }
2549
+ }
2550
+ // assumption: this redirect will trigger login flow callbacks in program.cs
2551
+ instance.acquireTokenRedirect({
2552
+ scopes: [apiScope],
2553
+ account: account
2554
+ });
2555
+ }
2556
+ catch (error: any) {
2557
+ console.log("Front end mindline token redirect acquisition failure: " + error);
2558
+ }
2559
+ }
2560
+ headers.append("Authorization", `Bearer ${user.mindlineAccessToken}`);
2561
+ return headers;
2562
+ }
2563
+ export async function processErrors(response: Response): Promise<string> {
2564
+ let errorString: string = "";
2565
+ if (response.status === 401) {
2566
+ errorString = response.statusText;
2567
+ if (errorString != "") return errorString;
2568
+ }
2569
+ let data = await response.json();
2570
+ // process errors from Mindline Config API
2571
+ if (data.error !== undefined) {
2572
+ errorString = `Error: ${data.error} Message: ${data.message}`;
2573
+ } else if (data.errors !== undefined) {
2574
+ let errorArray = Object.keys(data.errors);
2575
+ let errorlist: string = "";
2576
+ errorString = errorArray.reduce(
2577
+ (acc, curr) => acc + curr + ": " + data.errors[curr] + " ",
2578
+ errorlist
2579
+ );
2580
+ } else if (data.title !== undefined) {
2581
+ errorString = data.title;
2582
+ } else {
2583
+ debugger;
2584
+ }
2585
+ return errorString;
2586
+ }
2587
+ //adminDelete
2588
+ export async function adminDelete(
2589
+ instance: IPublicClientApplication,
2590
+ authorizedUser: User,
2591
+ user: User,
2592
+ workspaceId: string
2593
+ ): Promise<APIResult> {
2594
+ let result: APIResult = new APIResult();
2595
+ // we need either oid or mail for the user and valid workspace id
2596
+ if ((user.oid == "" && user.mail == "") || workspaceId == "") {
2597
+ result.result = false;
2598
+ result.error = "adminDelete: invalid parameters";
2599
+ result.status = 500;
2600
+ return result;
2601
+ }
2602
+ // define admin endpoint and add workspaceId parameter
2603
+ let url: URL | null = null;
2604
+ url = new URL(mindlineConfig.adminEndpoint());
2605
+ url.searchParams.append("workspaceId", workspaceId);
2606
+ url.searchParams.append("email", user.mail);
2607
+ // create headers
2608
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
2609
+ // make endpoint call
2610
+ let options = { method: "DELETE", headers: headers };
2611
+ try {
2612
+ console.log("Attempting DELETE from /admin: " + url!.href);
2613
+ let response = await fetch(url!.href, options);
2614
+ if (response.status === 200 && response.statusText === "OK") {
2615
+ console.log(`Successful DELETE from /admin: ${url!.href}`);
2616
+ return result;
2617
+ } else {
2618
+ result.error = await processErrors(response);
2619
+ console.log(`Failed DELETE from /admin: ${url.href}`);
2620
+ console.log(result.error);
2621
+ result.status = 500;
2622
+ result.result = false;
2623
+ return result;
2624
+ }
2625
+ } catch (error: any) {
2626
+ result.error = error.message;
2627
+ result.status = 500;
2628
+ result.result = false;
2629
+ console.log(error.message);
2630
+ }
2631
+ return result;
2632
+ }
2633
+ //adminsGet
2634
+ export async function adminsGet(
2635
+ instance: IPublicClientApplication,
2636
+ user: User,
2637
+ workspaceID: string,
2638
+ debug: boolean
2639
+ ): Promise<APIResult> {
2640
+ let result: APIResult = new APIResult();
2641
+ // we need a workspace id
2642
+ if (workspaceID === "") {
2643
+ result.result = false;
2644
+ result.status = 500;
2645
+ result.error = "adminsGet: no workspace provided";
2646
+ return result;
2647
+ }
2648
+ // create endpoint
2649
+ let endpoint: string = mindlineConfig.adminsEndpoint();
2650
+ // add parameter to endpoint
2651
+ let url: URL = new URL(endpoint);
2652
+ url.searchParams.append("workspaceId", workspaceID);
2653
+ // create headers
2654
+ const headers = await mindlineDefineHeaders(instance, user);
2655
+ // make endpoint call
2656
+ let options = { method: "GET", headers: headers };
2657
+ try {
2658
+ if (debug) debugger;
2659
+ console.log("Attempting GET from /admins: " + url.href);
2660
+ let response = await fetch(url.href, options);
2661
+ if (response.status === 200 && response.statusText === "OK") {
2662
+ let returnedArray: Array<Object> = await response.json();
2663
+ if (returnedArray != null) {
2664
+ result.array = returnedArray;
2665
+ let initialValue: string = "";
2666
+ console.log(`Successful GET from /admins: ${result.array.reduce((acc, curr) => acc + curr.email + " ", initialValue)}`);
2667
+ return result;
2668
+ }
2669
+ else {
2670
+ result.error = `Failed GET from /admins: failed to JSON-parse response`;
2671
+ console.log(result.error);
2672
+ result.status = 500;
2673
+ result.result = false;
2674
+ return result;
2675
+ }
2676
+ }
2677
+ else {
2678
+ console.log(`Failed GET from /admins: ${url.href}`);
2679
+ result.error = await processErrors(response);
2680
+ result.status = 500;
2681
+ result.result = false;
2682
+ console.log(result.error);
2683
+ return result;
2684
+ }
2685
+ }
2686
+ catch (error: any) {
2687
+ result.error = error.message;
2688
+ result.status = 500;
2689
+ result.result = false;
2690
+ console.log(error.message);
2691
+ }
2692
+ return result;
2693
+ }
2694
+ //adminPost: write validated admin to back end
2695
+ export async function adminPost(
2696
+ instance: IPublicClientApplication,
2697
+ authorizedUser: User,
2698
+ user: User,
2699
+ workspaceId: string
2700
+ ): Promise<APIResult> {
2701
+ let result: APIResult = new APIResult();
2702
+ if (user.mail == "" || user.authority == "" || user.tid === "") {
2703
+ result.result = false;
2704
+ result.error = "adminPost: invalid argument";
2705
+ result.status = 500;
2706
+ return result;
2707
+ }
2708
+ // create admin endpoint
2709
+ let endpoint: string = mindlineConfig.adminEndpoint();
2710
+ // create headers
2711
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
2712
+ // create admin body
2713
+ let adminBody: string = `
2714
+ {"email": "${user.mail}",
2715
+ "tenantId": "${user.tid}",
2716
+ "workspaceId": "${workspaceId}"
2717
+ }`;
2718
+ let options = { method: "POST", headers: headers, body: adminBody };
2719
+ // make admin endpoint call
2720
+ try {
2721
+ console.log("Attempting POST to /admin: " + endpoint);
2722
+ let response = await fetch(endpoint, options);
2723
+ if (response.status === 200 && response.statusText === "OK") {
2724
+ console.log(`Successful POST to /admin: ${adminBody}`);
2725
+ return result;
2726
+ } else {
2727
+ result.error = await processErrors(response);
2728
+ console.log(`Failed POST to /admin: ${adminBody}`);
2729
+ console.log(result.error);
2730
+ result.status = 500;
2731
+ result.result = false;
2732
+ return result;
2733
+ }
2734
+ } catch (error: any) {
2735
+ result.error = error.message;
2736
+ result.status = 500;
2737
+ result.result = false;
2738
+ console.log(error.message);
2739
+ }
2740
+ return result;
2741
+ }
2742
+ //configConsentReadPut
2743
+ export async function configConsentReadPut(instance: IPublicClientApplication, authorizedUser: User, configId: string, tid: string, consent: boolean): Promise<APIResult> {
2744
+ let result: APIResult = new APIResult();
2745
+ // create parameterized config consent endpoint
2746
+ let endpoint: string = mindlineConfig.configConsentEndpoint();
2747
+ let url: URL = new URL(endpoint);
2748
+ url.searchParams.append("configurationId", configId);
2749
+ // create headers
2750
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
2751
+ // create body
2752
+ let configConsentReadBody: string = `
2753
+ {
2754
+ "tenantId": "${tid}",
2755
+ "isReadPermissionConsented": ${consent ? "true" : "false"}
2756
+ }`;
2757
+ // make endpoint call
2758
+ let options = { method: "PUT", headers: headers, body: configConsentReadBody };
2759
+ try {
2760
+ console.log("Attempting PUT read consent to /configuration/consent: " + url.href);
2761
+ let response = await fetch(url.href, options);
2762
+ if (response.status === 200 && response.statusText === "OK") {
2763
+ console.log(`Successful PUT to ${url.href}`);
2764
+ return result;
2765
+ }
2766
+ else {
2767
+ result.error = await processErrors(response);
2768
+ console.log(`Failed PUT to ${url.href}`);
2769
+ console.log(result.error);
2770
+ result.status = 500;
2771
+ result.result = false;
2772
+ return result;
2773
+ }
2774
+ }
2775
+ catch (error: any) {
2776
+ result.error = error.message;
2777
+ result.status = 500;
2778
+ result.result = false;
2779
+ console.log(error.message);
2780
+ }
2781
+ return result;
2782
+ }
2783
+ //configConsentWritePut
2784
+ export async function configConsentWritePut(instance: IPublicClientApplication, authorizedUser: User, configId: string, tid: string, consent: boolean): Promise<APIResult> {
2785
+ let result: APIResult = new APIResult();
2786
+ // create parameterized config consent endpoint
2787
+ let endpoint: string = mindlineConfig.configConsentEndpoint();
2788
+ let url: URL = new URL(endpoint);
2789
+ url.searchParams.append("configurationId", configId);
2790
+ // create headers
2791
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
2792
+ // create body
2793
+ let configConsentWriteBody: string = `
2794
+ {
2795
+ "tenantId": "${tid}",
2796
+ "isWritePermissionConsented": ${consent ? "true" : "false"}
2797
+ }`;
2798
+ // make endpoint call
2799
+ let options = { method: "PUT", headers: headers, body: configConsentWriteBody };
2800
+ try {
2801
+ console.log("Attempting PUT read consent to /configuration/consent: " + url.href);
2802
+ let response = await fetch(url.href, options);
2803
+ if (response.status === 200 && response.statusText === "OK") {
2804
+ console.log(`Successful PUT to ${url.href}`);
2805
+ return result;
2806
+ }
2807
+ else {
2808
+ result.error = await processErrors(response);
2809
+ console.log(`Failed PUT to ${url.href}`);
2810
+ console.log(result.error);
2811
+ result.status = 500;
2812
+ result.result = false;
2813
+ return result;
2814
+ }
2815
+ }
2816
+ catch (error: any) {
2817
+ result.error = error.message;
2818
+ result.status = 500;
2819
+ result.result = false;
2820
+ console.log(error.message);
2821
+ }
2822
+ return result;
2823
+ }
2824
+ //configDelete
2825
+ export async function configDelete(
2826
+ instance: IPublicClientApplication,
2827
+ authorizedUser: User,
2828
+ config: Config,
2829
+ workspaceId: string,
2830
+ debug: boolean
2831
+ ): Promise<APIResult> {
2832
+ let result: APIResult = new APIResult();
2833
+ if (config.id === "" || workspaceId == "") {
2834
+ result.result = false;
2835
+ result.error = "configPost: invalid config ID";
2836
+ result.status = 500;
2837
+ return result;
2838
+ }
2839
+ let url: URL | null = null;
2840
+ url = new URL(mindlineConfig.configEndpoint());
2841
+ url.searchParams.append("configurationId", config.id);
2842
+ // create headers
2843
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
2844
+ // make endpoint call
2845
+ let options = { method: "DELETE", headers: headers };
2846
+ try {
2847
+ console.log("Attempting DELETE from /config: " + url.href);
2848
+ let response = await fetch(url.href, options);
2849
+ if (response.status === 200 && response.statusText === "OK") {
2850
+ console.log(`Successful DELETE from /config`);
2851
+ return result;
2852
+ }
2853
+ else {
2854
+ result.error = await processErrors(response);
2855
+ console.log(`Failed DELETE from ${url.href}`);
2856
+ console.log(result.error);
2857
+ result.status = 500;
2858
+ result.result = false;
2859
+ return result;
2860
+ }
2861
+ }
2862
+ catch (error: any) {
2863
+ result.error = error.message;
2864
+ result.status = 500;
2865
+ result.result = false;
2866
+ console.log(error.message);
2867
+ }
2868
+ return result;
2869
+ }
2870
+ //configPatch
2871
+ export async function configPatch(
2872
+ instance: IPublicClientApplication,
2873
+ authorizedUser: User,
2874
+ configurationId: string,
2875
+ enabled: boolean,
2876
+ debug: boolean
2877
+ ): Promise<APIResult> {
2878
+ let result: APIResult = new APIResult();
2879
+ if (configurationId === "") {
2880
+ result.result = false;
2881
+ result.error = "configPatch: invalid config ID";
2882
+ result.status = 500;
2883
+ return result;
2884
+ }
2885
+ // create parametrized config endpoint
2886
+ let endpoint: string = mindlineConfig.configEnabledEndpoint();
2887
+ let url: URL = new URL(endpoint);
2888
+ url.searchParams.append("configurationId", configurationId);
2889
+ url.searchParams.append("isEnabled", enabled.toString());
2890
+ // create config headers
2891
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
2892
+ let options = { method: "PATCH", headers: headers };
2893
+ // make config endpoint call
2894
+ try {
2895
+ if (debug) debugger;
2896
+ console.log("Attempting PATCH to /config: " + url.href);
2897
+ let response = await fetch(url.href, options);
2898
+ if (response.status === 200 && response.statusText === "OK") {
2899
+ console.log(`Successful PATCH to ${url.href}: ${enabled.toString()}`);
2900
+ return result;
2901
+ }
2902
+ else {
2903
+ result.error = await processErrors(response);
2904
+ console.log(`Failed PATCH to ${url.href}: ${enabled.toString()}`);
2905
+ console.log(result.error);
2906
+ result.status = 500;
2907
+ result.result = false;
2908
+ return result;
2909
+ }
2910
+ }
2911
+ catch (error: any) {
2912
+ result.error = error.message;
2913
+ result.status = 500;
2914
+ result.result = false;
2915
+ console.log(error.message);
2916
+ }
2917
+ return result;
2918
+ }
2919
+ //configPost
2920
+ export async function configPost(
2921
+ instance: IPublicClientApplication,
2922
+ authorizedUser: User,
2923
+ config: Config,
2924
+ workspaceId: string,
2925
+ debug: boolean
2926
+ ): Promise<APIResult> {
2927
+ let result: APIResult = new APIResult();
2928
+ if (config.id === "") {
2929
+ result.result = false;
2930
+ result.error = "configPost: invalid config ID";
2931
+ result.status = 500;
2932
+ return result;
2933
+ }
2934
+ // create no parameter config endpoint
2935
+ let endpoint: string = mindlineConfig.configEndpoint();
2936
+ // create config headers
2937
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
2938
+ // create config body
2939
+ let configBody: string = `
2940
+ {
2941
+ "workspaceId": "${workspaceId}",
2942
+ "name": "${config.name}",
2943
+ "description": "${config.description}",
2944
+ "isEnabled": ${config.isEnabled},
2945
+ "tenants": [`;
2946
+ config.tenants.map((tci) => {
2947
+ // be sure we send null and not "null" in body
2948
+ let sourceGroupId: string = tci.sourceGroupId != "" ? `"${tci.sourceGroupId}"` : "null";
2949
+ let sourceGroupName: string = tci.sourceGroupName != "" ? `"${tci.sourceGroupName}"` : "null";
2950
+ let targetGroupId: string = tci.targetGroupId != "" ? `"${tci.targetGroupId}"` : "null";
2951
+ let targetGroupName: string = tci.targetGroupName != "" ? `"${tci.targetGroupName}"` : "null";
2952
+ // if last character is } we need a comma first
2953
+ let needComma: boolean = configBody.slice(-1) === "}";
2954
+ if (needComma) configBody += ",";
2955
+ configBody += `{
2956
+ "tenantId": "${tci.tid}",
2957
+ "sourceGroupId": ${sourceGroupId},
2958
+ "sourceGroupName": ${sourceGroupName},
2959
+ "targetGroupId": ${targetGroupId},
2960
+ "targetGroupName": ${targetGroupName},
2961
+ "configurationTenantType": "${tci.configurationTenantType}"
2962
+ }`;
2963
+ });
2964
+ configBody += `]}`;
2965
+ let options = { method: "POST", headers: headers, body: configBody };
2966
+ // make config endpoint call
2967
+ try {
2968
+ if (debug) debugger;
2969
+ console.log("Attempting POST to /config: " + endpoint);
2970
+ let response = await fetch(endpoint, options);
2971
+ if (response.status === 200 && response.statusText === "OK") {
2972
+ let data = await response.json();
2973
+ config.id = data;
2974
+ console.log(
2975
+ `Successful ConfigID: ${data} from POST to /config: ${configBody}`
2976
+ );
2977
+ return result;
2978
+ }
2979
+ else {
2980
+ result.error = await processErrors(response);
2981
+ console.log(`Failed PUT to /config: ${configBody}`);
2982
+ console.log(result.error);
2983
+ result.status = 500;
2984
+ result.result = false;
2985
+ return result;
2986
+ }
2987
+ }
2988
+ catch (error: any) {
2989
+ result.status = 500;
2990
+ result.result = false;
2991
+ result.error = error.message;
2992
+ console.log(result.error);
2993
+ return result;
2994
+ }
2995
+ }
2996
+ //configPut
2997
+ export async function configPut(
2998
+ instance: IPublicClientApplication,
2999
+ authorizedUser: User,
3000
+ config: Config,
3001
+ debug: boolean
3002
+ ): Promise<APIResult> {
3003
+ let result: APIResult = new APIResult();
3004
+ if (config.id === "") {
3005
+ result.result = false;
3006
+ result.error = "configPost: invalid config ID";
3007
+ result.status = 500;
3008
+ return result;
3009
+ }
3010
+ // create parametrized config endpoint
3011
+ let endpoint: string = mindlineConfig.configEndpoint();
3012
+ let url: URL = new URL(endpoint);
3013
+ url.searchParams.append("configurationId", config.id);
3014
+ // create config headers
3015
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
3016
+ // create config body
3017
+ let configBody: string = `
3018
+ {
3019
+ "name": "${config.name}",
3020
+ "description": "${config.description}",
3021
+ "tenants": [`;
3022
+ config.tenants.map((tci: TenantConfigInfo) => {
3023
+ // if last character is } we need a comma first
3024
+ let needComma: boolean = configBody.slice(-1) === "}";
3025
+ if (needComma) configBody += ",";
3026
+ // be sure we send null and not "null" in body
3027
+ let sourceGroupId: string = tci.sourceGroupId != "" ? `"${tci.sourceGroupId}"` : "null";
3028
+ let sourceGroupName: string = tci.sourceGroupName != "" ? `"${tci.sourceGroupName}"` : "null";
3029
+ let targetGroupId: string = tci.targetGroupId != "" ? `"${tci.targetGroupId}"` : "null";
3030
+ let targetGroupName: string = tci.targetGroupName != "" ? `"${tci.targetGroupName}"` : "null";
3031
+ configBody += `{
3032
+ "tenantId": "${tci.tid}",
3033
+ "sourceGroupId": ${sourceGroupId},
3034
+ "sourceGroupName": ${sourceGroupName},
3035
+ "targetGroupId": ${targetGroupId},
3036
+ "targetGroupName": ${targetGroupName},
3037
+ "configurationTenantType": "${tci.configurationTenantType}",
3038
+ "deltaToken": "${tci.deltaToken}"
3039
+ }`;
3040
+ });
3041
+ configBody += `]}`;
3042
+ let options = { method: "PUT", headers: headers, body: configBody };
3043
+ // make config endpoint call
3044
+ try {
3045
+ if (debug) debugger;
3046
+ console.log("Attempting PUT to /config: " + url.href);
3047
+ let response = await fetch(url.href, options);
3048
+ if (response.status === 200 && response.statusText === "OK") {
3049
+ console.log(`Successful PUT to ${url.href}: ${configBody}`);
3050
+ return result;
3051
+ }
3052
+ else {
3053
+ result.error = await processErrors(response);
3054
+ console.log(`Failed PUT to ${url.href}: ${configBody}`);
3055
+ console.log(result.error);
3056
+ result.status = 500;
3057
+ result.result = false;
3058
+ return result;
3059
+ }
3060
+ }
3061
+ catch (error: any) {
3062
+ result.error = error.message;
3063
+ result.status = 500;
3064
+ result.result = false;
3065
+ console.log(error.message);
3066
+ }
3067
+ return result;
3068
+ }
3069
+ //configsGet
3070
+ export async function configsGet(
3071
+ instance: IPublicClientApplication,
3072
+ user: User,
3073
+ workspaceID: string,
3074
+ debug: boolean
3075
+ ): Promise<APIResult> {
3076
+ let result: APIResult = new APIResult();
3077
+ // we need a workspace id
3078
+ if (workspaceID === "") {
3079
+ result.result = false;
3080
+ result.status = 500;
3081
+ result.error = "configsGet: no workspace provided";
3082
+ return result;
3083
+ }
3084
+ // create endpoint
3085
+ let endpoint: string = mindlineConfig.configsEndpoint();
3086
+ // add parameter to endpoint
3087
+ let url: URL = new URL(endpoint);
3088
+ url.searchParams.append("workspaceId", workspaceID);
3089
+ // create headers
3090
+ const headers = await mindlineDefineHeaders(instance, user);
3091
+ // make endpoint call
3092
+ let options = { method: "GET", headers: headers };
3093
+ try {
3094
+ if (debug) debugger;
3095
+ console.log("Attempting GET from /configurations: " + url.href);
3096
+ let response = await fetch(url.href, options);
3097
+ if (response.status === 200 && response.statusText === "OK") {
3098
+ let returnedArray: Array<Object> = await response.json();
3099
+ if (returnedArray != null) {
3100
+ result.array = returnedArray;
3101
+ let initialValue: string = "";
3102
+ console.log(`Successful GET from /configurations: ${result.array.reduce((acc, curr) => acc + curr.name + " ", initialValue)}`);
3103
+ return result;
3104
+ }
3105
+ else {
3106
+ result.error = `Failed GET from /configurations: failed to JSON-parse response`;
3107
+ console.log(result.error);
3108
+ result.status = 500;
3109
+ result.result = false;
3110
+ return result;
3111
+ }
3112
+ }
3113
+ else {
3114
+ console.log(`Failed GET from /configurations: ${url.href}`);
3115
+ result.error = await processErrors(response);
3116
+ result.status = 500;
3117
+ result.result = false;
3118
+ console.log(result.error);
3119
+ return result;
3120
+ }
3121
+ }
3122
+ catch (error: any) {
3123
+ result.error = error.message;
3124
+ result.status = 500;
3125
+ result.result = false;
3126
+ console.log(error.message);
3127
+ }
3128
+ return result;
3129
+ }
3130
+ //initPost
3131
+ export async function initPost(
3132
+ instance: IPublicClientApplication,
3133
+ user: User,
3134
+ debug: boolean
3135
+ ): Promise<APIResult> {
3136
+ let result: APIResult = new APIResult();
3137
+ // we expect valid company name and domain by this point
3138
+ if (user.companyName === "" || user.companyDomain === "") {
3139
+ result.result = false;
3140
+ result.error = "initPost: invalid company name or domain"
3141
+ result.status = 500;
3142
+ return result;
3143
+ }
3144
+ // create init endpoint
3145
+ let endpoint: string = mindlineConfig.initEndpoint();
3146
+ // create init headers
3147
+ const headers = await mindlineDefineHeaders(instance, user);
3148
+ // create init body
3149
+ let initBody: string = `
3150
+ {
3151
+ "tenantCreateModel": {
3152
+ "tenantId": "${user.tid}",
3153
+ "name": "${user.companyName}",
3154
+ "domain": "${user.companyDomain}",
3155
+ "type": "aad",
3156
+ "authority": "${user.authority}"
3157
+ }
3158
+ }`;
3159
+ let options = { method: "POST", headers: headers, body: initBody };
3160
+ // make init endpoint call
3161
+ try {
3162
+ if (debug) debugger;
3163
+ console.log("Attempting POST to /configuration/init: " + endpoint);
3164
+ let response = await fetch(endpoint, options);
3165
+ if (response.status === 200 && response.statusText === "OK") {
3166
+ console.log(`Successful POST to /configuration/init: ${initBody}`);
3167
+ return result;
3168
+ }
3169
+ else {
3170
+ result.error = await processErrors(response);
3171
+ result.status = 500;
3172
+ result.result = false;
3173
+ console.log(`Failed POST to /configuration/init: ${initBody}`);
3174
+ console.log(result.error);
3175
+ return result;
3176
+ }
3177
+ }
3178
+ catch (error: any) {
3179
+ result.error = error.message;
3180
+ console.log(result.error);
3181
+ }
3182
+ result.status = 500;
3183
+ result.result = false;
3184
+ return result;
3185
+ }
3186
+ //tenantDelete
3187
+ export async function tenantDelete(
3188
+ instance: IPublicClientApplication,
3189
+ authorizedUser: User,
3190
+ tenant: Tenant,
3191
+ workspaceId: string,
3192
+ debug: boolean
3193
+ ): Promise<APIResult> {
3194
+ let result: APIResult = new APIResult();
3195
+ // we expect valid tid amd workspaceId
3196
+ if (tenant.tid === "" || workspaceId === "") {
3197
+ result.result = false;
3198
+ result.error = "tenantDelete: invalid tid, workspaceId";
3199
+ result.status = 500;
3200
+ return result;
3201
+ }
3202
+ // create parametrized tenant endpoint
3203
+ let url: URL = new URL(mindlineConfig.tenantEndpoint());
3204
+ url.searchParams.append("tenantId", tenant.tid);
3205
+ url.searchParams.append("workspaceId", workspaceId);
3206
+ // create headers
3207
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
3208
+ // make tenant endpoint call
3209
+ let options = { method: "DELETE", headers: headers };
3210
+ try {
3211
+ console.log("Attempting DELETE from /tenant: " + url.href);
3212
+ let response = await fetch(url.href, options);
3213
+ if (response.status === 200 && response.statusText === "OK") {
3214
+ console.log(`Successful DELETE from /tenant: ${url.href}`);
3215
+ return result;
3216
+ }
3217
+ else {
3218
+ console.log(`Failed DELETE from /tenant: ${url.href}`);
3219
+ result.error = await processErrors(response);
3220
+ console.log(result.error);
3221
+ result.status = 500;
3222
+ result.result = false;
3223
+ return result;
3224
+ }
3225
+ }
3226
+ catch (error: any) {
3227
+ result.error = error.message;
3228
+ result.status = 500;
3229
+ result.result = false;
3230
+ console.log(result.error);
3231
+ }
3232
+ return result;
3233
+ }
3234
+ //tenantsGet
3235
+ export async function tenantsGet(
3236
+ instance: IPublicClientApplication,
3237
+ user: User,
3238
+ workspaceID: string,
3239
+ debug: boolean
3240
+ ): Promise<APIResult> {
3241
+ let result: APIResult = new APIResult();
3242
+ // we need a workspace id
3243
+ if (workspaceID === "") {
3244
+ result.result = false;
3245
+ result.status = 500;
3246
+ result.error = "tenantsGet: no workspace provided";
3247
+ return result;
3248
+ }
3249
+ // create endpoint
3250
+ let endpoint: string = mindlineConfig.tenantsEndpoint();
3251
+ // add parameter to endpoint
3252
+ let url: URL = new URL(endpoint);
3253
+ url.searchParams.append("workspaceId", workspaceID);
3254
+ // create headers
3255
+ const headers = await mindlineDefineHeaders(instance, user);
3256
+ // make endpoint call
3257
+ let options = { method: "GET", headers: headers };
3258
+ try {
3259
+ if (debug) debugger;
3260
+ console.log(`Attempting GET from /tenants: ${url.href}`);
3261
+ let response = await fetch(url.href, options);
3262
+ if (response.status === 200 && response.statusText === "OK") {
3263
+ let returnedArray: Array<Object> = await response.json();
3264
+ if (returnedArray != null) {
3265
+ result.array = returnedArray;
3266
+ let initialValue: string = "";
3267
+ console.log(`Successful GET from /tenants: ${result.array.reduce((acc, curr) => acc + curr.domain + " ", initialValue)}`);
3268
+ return result;
3269
+ }
3270
+ else {
3271
+ result.error = `Failed GET from /tenants: failed to JSON-parse response`;
3272
+ console.log(result.error);
3273
+ result.status = 500;
3274
+ result.result = false;
3275
+ return result;
3276
+ }
3277
+ }
3278
+ else {
3279
+ console.log(`Failed GET from /tenants: ${url.href}`);
3280
+ result.error = await processErrors(response);
3281
+ result.status = 500;
3282
+ result.result = false;
3283
+ console.log(result.error);
3284
+ return result;
3285
+ }
3286
+ }
3287
+ catch (error: any) {
3288
+ result.error = error.message;
3289
+ result.status = 500;
3290
+ result.result = false;
3291
+ console.log(error.message);
3292
+ }
3293
+ return result;
3294
+ }
3295
+ //tenantPost: write validated tenant to back end
3296
+ export async function tenantPost(
3297
+ instance: IPublicClientApplication,
3298
+ addingUser: User,
3299
+ tenant: Tenant,
3300
+ workspaceId: string
3301
+ ): Promise<APIResult> {
3302
+ let result: APIResult = new APIResult();
3303
+ // we expect valid tid, name, validated domain
3304
+ if (tenant.tid === "" || tenant.name === "" || tenant.domain === "") {
3305
+ result.result = false;
3306
+ result.error = "tenantPost: invalid tid, name, domain";
3307
+ result.status = 500;
3308
+ return result;
3309
+ }
3310
+ // create parametrized tenant endpoint
3311
+ let endpoint: string = mindlineConfig.tenantEndpoint();
3312
+ let url: URL = new URL(endpoint);
3313
+ url.searchParams.append("workspaceId", workspaceId);
3314
+ // create tenant headers
3315
+ const headers = await mindlineDefineHeaders(instance, addingUser);
3316
+ // create tenant body
3317
+ let tenantBody: string = `
3318
+ {"tenantId": "${tenant.tid}",
3319
+ "name": "${tenant.name}",
3320
+ "domain": "${tenant.domain}",
3321
+ "type": 1,
3322
+ "authority": "${tenant.authority}"
3323
+ }`;
3324
+ let options = { method: "POST", headers: headers, body: tenantBody };
3325
+ // make tenant endpoint call
3326
+ try {
3327
+ console.log(`Attempting POST to ${url.href}: ${tenantBody}`);
3328
+ let response = await fetch(url.href, options);
3329
+ if (response.status === 200 && response.statusText === "OK") {
3330
+ console.log(`Successful POST to ${url.href}: ${tenantBody}`);
3331
+ return result;
3332
+ }
3333
+ else {
3334
+ console.log(`Failed POST to ${url.href}: ${tenantBody}`);
3335
+ result.error = await processErrors(response);
3336
+ console.log(result.error);
3337
+ result.status = 500;
3338
+ result.result = false;
3339
+ return result;
3340
+ }
3341
+ }
3342
+ catch (error: any) {
3343
+ result.error = error.message;
3344
+ result.status = 500;
3345
+ result.result = false;
3346
+ console.log(result.error);
3347
+ }
3348
+ return result;
3349
+ }
3350
+ //workspacePut
3351
+ export async function workspacePut(instance: IPublicClientApplication, authorizedUser: User, workspaceId: string, workspaceName: string): Promise<APIResult> {
3352
+ let result: APIResult = new APIResult();
3353
+ if (workspaceId == "" || workspaceName == "") {
3354
+ result.result = false;
3355
+ result.error = "workspacePut: invalid workspace ID or name";
3356
+ result.status = 500;
3357
+ return result;
3358
+ }
3359
+ // create parameterized workspace endpoint
3360
+ let endpoint: string = mindlineConfig.workspaceEndpoint();
3361
+ let url: URL = new URL(endpoint);
3362
+ url.searchParams.append("workspaceId", workspaceId);
3363
+ url.searchParams.append("workspaceName", workspaceName);
3364
+ // create workspace headers
3365
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
3366
+ let options = { method: "PUT", headers: headers };
3367
+ // make config endpoint call
3368
+ try {
3369
+ console.log("Attempting PUT to /workspace: " + url.href);
3370
+ let response = await fetch(url.href, options);
3371
+ if (response.status === 200 && response.statusText === "OK") {
3372
+ console.log(`Successful PUT to ${url.href}`);
3373
+ return result;
3374
+ }
3375
+ else {
3376
+ result.error = await processErrors(response);
3377
+ console.log(`Failed PUT to ${url.href}`);
3378
+ console.log(result.error);
3379
+ result.status = 500;
3380
+ result.result = false;
3381
+ return result;
3382
+ }
3383
+ }
3384
+ catch (error: any) {
3385
+ result.error = error.message;
3386
+ result.status = 500;
3387
+ result.result = false;
3388
+ console.log(error.message);
3389
+ }
3390
+ return result;
3391
+ }
3392
+ //workspacesGet
3393
+ export async function workspacesGet(
3394
+ instance: IPublicClientApplication,
3395
+ user: User,
3396
+ debug: boolean
3397
+ ): Promise<APIResult> {
3398
+ let result: APIResult = new APIResult();
3399
+ // we need a valid email address
3400
+ if (user.mail == undefined || user.mail == "") {
3401
+ result.result = false;
3402
+ result.status = 500;
3403
+ result.error = "adminsGet: no workspace provided";
3404
+ return result;
3405
+ }
3406
+ // create workspaces endpoint
3407
+ let endpoint: string = mindlineConfig.workspacesEndpoint();
3408
+ // create workspace endpoint
3409
+ let url: URL = new URL(endpoint);
3410
+ // create workspace headers
3411
+ const headers = await mindlineDefineHeaders(instance, user);
3412
+ // make workspace endpoint call
3413
+ let options = { method: "GET", headers: headers };
3414
+ try {
3415
+ if (debug) debugger;
3416
+ console.log("Attempting GET from /workspaces endpoint: " + url.href);
3417
+ let response = await fetch(url.href, options);
3418
+ if (response.status === 200 && response.statusText === "OK") {
3419
+ let returnedArray: Array<Object> = await response.json();
3420
+ if (returnedArray != null) {
3421
+ result.array = returnedArray;
3422
+ let initialValue: string = "";
3423
+ console.log(`Successful GET from /workspaces: ${result.array.reduce((acc, curr) => acc + curr.name + " ", initialValue)}`);
3424
+ return result;
3425
+ }
3426
+ else {
3427
+ result.error = `Failed GET from /workspaces: failed to JSON-parse response`;
3428
+ console.log(result.error);
3429
+ result.status = 500;
3430
+ result.result = false;
3431
+ return result;
3432
+ }
3433
+ }
3434
+ else {
3435
+ console.log(`Failed GET from /workspaces: ${url.href}`);
3436
+ result.error = await processErrors(response);
3437
+ result.status = 500;
3438
+ result.result = false;
3439
+ console.log(result.error);
3440
+ return result;
3441
+ }
3442
+ }
3443
+ catch (error: any) {
3444
+ result.error = error.message;
3445
+ result.status = 500;
3446
+ result.result = false;
3447
+ console.log(error.message);
3448
+ }
3449
+ return result;
3450
+ }
3451
+ //readerPost
3452
+ export async function readerPost(
3453
+ instance: IPublicClientApplication,
3454
+ authorizedUser: User,
3455
+ config: Config
3456
+ ): Promise<APIResult> {
3457
+ let result: APIResult = new APIResult();
3458
+ if (instance == null || authorizedUser == null) {
3459
+ result.result = false;
3460
+ result.error = "readerPost: invalid parameters";
3461
+ result.status = 500;
3462
+ return result;
3463
+ }
3464
+ // create reader endpoint
3465
+ let readerEndpoint: string = mindlineConfig.readerStartSyncEndpoint();
3466
+ let url: URL = new URL(readerEndpoint);
3467
+ url.searchParams.append("configurationId", config.id);
3468
+ // create headers
3469
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
3470
+ // make reader endpoint call
3471
+ let options = { method: "POST", headers: headers };
3472
+ try {
3473
+ console.log("Attempting POST to /startSync: " + url.href);
3474
+ let response = await fetch(url.href, options);
3475
+ if (response.status === 200 && response.statusText === "OK") {
3476
+ console.log(`Successful POST to /startSync: ${readerEndpoint}`);
3477
+ let jsonResponse = await response.json();
3478
+ if (jsonResponse.PayloadStr != "") {
3479
+ result.array = JSON.parse(jsonResponse.PayloadStr);
3480
+ }
3481
+ else {
3482
+ result.result = false;
3483
+ result.error = "readerPost: blank payload returned, sync may be disabled on back end";
3484
+ result.status = 500;
3485
+ }
3486
+ return result;
3487
+ } else {
3488
+ result.error = await processErrors(response);
3489
+ console.log(`Failed POST to /startSync: ${readerEndpoint}`);
3490
+ console.log(result.error);
3491
+ result.status = 500;
3492
+ result.result = false;
3493
+ return result;
3494
+ }
3495
+ } catch (error: any) {
3496
+ result.error = error.message;
3497
+ result.status = 500;
3498
+ result.result = false;
3499
+ console.log(error.message);
3500
+ }
3501
+ return result;
2494
3502
  }