@mindline/sync 1.0.82 → 1.0.84

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.
@@ -2,6 +2,6 @@
2
2
  "ExpandedNodes": [
3
3
  ""
4
4
  ],
5
- "SelectedNode": "\\package.json",
5
+ "SelectedNode": "\\index.d.ts",
6
6
  "PreviewInSolutionExplorer": false
7
7
  }
package/.vs/slnx.sqlite CHANGED
Binary file
Binary file
@@ -11,12 +11,8 @@
11
11
  "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:index.ts||{0F2454B1-A556-402D-A7D0-1FDE7F99DEE0}"
12
12
  },
13
13
  {
14
- "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\package.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}",
15
- "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:package.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
16
- },
17
- {
18
- "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\users.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}",
19
- "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:users.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
14
+ "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\index.d.ts||{0F2454B1-A556-402D-A7D0-1FDE7F99DEE0}",
15
+ "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:index.d.ts||{0F2454B1-A556-402D-A7D0-1FDE7F99DEE0}"
20
16
  }
21
17
  ],
22
18
  "DocumentGroupContainers": [
@@ -64,33 +60,40 @@
64
60
  },
65
61
  {
66
62
  "DockedWidth": 200,
67
- "SelectedChildIndex": 2,
63
+ "SelectedChildIndex": 1,
68
64
  "Children": [
69
65
  {
70
66
  "$type": "Document",
71
67
  "DocumentIndex": 2,
72
- "Title": "package.json",
73
- "DocumentMoniker": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\package.json",
74
- "RelativeDocumentMoniker": "package.json",
75
- "ToolTip": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\package.json",
76
- "RelativeToolTip": "package.json",
77
- "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
78
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
79
- "WhenOpened": "2024-11-06T06:24:37.385Z",
68
+ "Title": "index.d.ts",
69
+ "DocumentMoniker": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\index.d.ts",
70
+ "RelativeDocumentMoniker": "index.d.ts",
71
+ "ToolTip": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\index.d.ts",
72
+ "RelativeToolTip": "index.d.ts",
73
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAABoAAAAoAAAA",
74
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003213|",
75
+ "WhenOpened": "2025-01-29T23:22:53.18Z",
80
76
  "EditorCaption": ""
81
77
  },
82
78
  {
83
79
  "$type": "Document",
84
- "DocumentIndex": 3,
85
- "Title": "users.json",
86
- "DocumentMoniker": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\users.json",
87
- "RelativeDocumentMoniker": "users.json",
88
- "ToolTip": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\users.json",
89
- "RelativeToolTip": "users.json",
90
- "ViewState": "AQIAAAAAAAAAAAAAAAAAAAUAAAASAAAA",
91
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
92
- "WhenOpened": "2024-11-05T22:57:19.003Z"
93
- },
80
+ "DocumentIndex": 1,
81
+ "Title": "index.ts",
82
+ "DocumentMoniker": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\index.ts",
83
+ "RelativeDocumentMoniker": "index.ts",
84
+ "ToolTip": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\index.ts",
85
+ "RelativeToolTip": "index.ts",
86
+ "ViewState": "AQIAACgAAAAAAAAAAADwvzMAAAAEAAAA",
87
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003213|",
88
+ "WhenOpened": "2025-01-29T14:51:05.763Z",
89
+ "EditorCaption": ""
90
+ }
91
+ ]
92
+ },
93
+ {
94
+ "DockedWidth": 200,
95
+ "SelectedChildIndex": 0,
96
+ "Children": [
94
97
  {
95
98
  "$type": "Document",
96
99
  "DocumentIndex": 0,
@@ -99,23 +102,10 @@
99
102
  "RelativeDocumentMoniker": "hybridspa.ts",
100
103
  "ToolTip": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\hybridspa.ts",
101
104
  "RelativeToolTip": "hybridspa.ts",
102
- "ViewState": "AQIAABwAAAAAAAAAAAAAABwAAAAUAAAA",
105
+ "ViewState": "AQIAAH4BAAAAAAAAAADwv5UBAAAiAAAA",
103
106
  "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003213|",
104
107
  "WhenOpened": "2024-11-04T14:16:26.493Z",
105
108
  "EditorCaption": ""
106
- },
107
- {
108
- "$type": "Document",
109
- "DocumentIndex": 1,
110
- "Title": "index.ts",
111
- "DocumentMoniker": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\index.ts",
112
- "RelativeDocumentMoniker": "index.ts",
113
- "ToolTip": "C:\\Users\\ArvindSuthar\\source\\repos\\front\\sync\\index.ts",
114
- "RelativeToolTip": "index.ts",
115
- "ViewState": "AQIAAPQGAAAAAAAAAAAswNQHAAAdAAAA",
116
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003213|",
117
- "WhenOpened": "2024-05-12T20:20:11.888Z",
118
- "EditorCaption": ""
119
109
  }
120
110
  ]
121
111
  },
package/hybridspa.ts CHANGED
@@ -37,10 +37,28 @@ async function mindlineDefineHeaders(
37
37
  const headers = new Headers();
38
38
  headers.append("Content-Type", "application/json");
39
39
  headers.append("accept", "*/*");
40
- // authorization header - if needed, retrieve and cache access token
41
- if (user.mindlineAccessToken == null || user.mindlineAccessToken === "") {
42
- const apiScope: string = getAPIScope(user);
40
+ // always call acquireTokenSilent, handling expired tokens on exception
41
+ const apiScope: string = getAPIScope(user);
42
+ try {
43
+ let accounts: AccountInfo[] = instance.getAllAccounts();
44
+ let homeAccountId = user.oid + "." + user.tid;
45
+ let account: AccountInfo = null;
46
+ for (let i: number = 0; i < accounts.length; i++) {
47
+ if (accounts[i].homeAccountId == homeAccountId) {
48
+ account = accounts[i];
49
+ }
50
+ }
51
+ let response: AuthenticationResult = await instance.acquireTokenSilent({
52
+ scopes: [apiScope],
53
+ account: account
54
+ });
55
+ user.mindlineAccessToken = response.accessToken; // cache access token
56
+ console.log("Front end mindline token acquired silently: " + user.mindlineAccessToken.slice(0, 20));
57
+ }
58
+ catch (error: any) {
43
59
  try {
60
+ console.log("Front end mindline token silent acquisition failure, triggering redirect: " + error);
61
+ // fallback to redirect if silent acquisition fails
44
62
  let accounts: AccountInfo[] = instance.getAllAccounts();
45
63
  let homeAccountId = user.oid + "." + user.tid;
46
64
  let account: AccountInfo = null;
@@ -49,33 +67,14 @@ async function mindlineDefineHeaders(
49
67
  account = accounts[i];
50
68
  }
51
69
  }
52
- let response: AuthenticationResult = await instance.acquireTokenSilent({
70
+ // assumption: this redirect will trigger login flow callbacks in program.cs
71
+ instance.acquireTokenRedirect({
53
72
  scopes: [apiScope],
54
73
  account: account
55
74
  });
56
- user.mindlineAccessToken = response.accessToken; // cache access token
57
- console.log("Front end token acquired silently: " + user.mindlineAccessToken.slice(0, 20));
58
75
  }
59
76
  catch (error: any) {
60
- try {
61
- console.log("Front end token silent acquisition failure: " + error);
62
- // fallback to redirect if silent acquisition fails
63
- let accounts: AccountInfo[] = instance.getAllAccounts();
64
- let homeAccountId = user.oid + "." + user.tid;
65
- let account: AccountInfo = null;
66
- for (let i: number = 0; i < accounts.length; i++) {
67
- if (accounts[i].homeAccountId == homeAccountId) {
68
- account = accounts[i];
69
- }
70
- }
71
- instance.acquireTokenRedirect({
72
- scopes: [apiScope],
73
- account: account
74
- });
75
- }
76
- catch (error: any) {
77
- console.log("Front end token popup acquisition failure: " + error);
78
- }
77
+ console.log("Front end mindline token redirect acquisition failure: " + error);
79
78
  }
80
79
  }
81
80
  headers.append("Authorization", `Bearer ${user.mindlineAccessToken}`);
@@ -88,8 +87,9 @@ export async function processErrors(response: Response): Promise<string> {
88
87
  if (errorString != "") return errorString;
89
88
  }
90
89
  let data = await response.json();
90
+ // process errors from Mindline Config API
91
91
  if (data.error !== undefined) {
92
- errorString = `Error: ${data.error.code} Message: ${data.error.message}`;
92
+ errorString = `Error: ${data.error} Message: ${data.message}`;
93
93
  } else if (data.errors !== undefined) {
94
94
  let errorArray = Object.keys(data.errors);
95
95
  let errorlist: string = "";
@@ -387,6 +387,55 @@ export async function configDelete(
387
387
  }
388
388
  return result;
389
389
  }
390
+ //configPatch
391
+ export async function configPatch(
392
+ instance: IPublicClientApplication,
393
+ authorizedUser: User,
394
+ configurationId: string,
395
+ enabled: boolean,
396
+ debug: boolean
397
+ ): Promise<APIResult> {
398
+ let result: APIResult = new APIResult();
399
+ if (configurationId === "") {
400
+ result.result = false;
401
+ result.error = "configPatch: invalid config ID";
402
+ result.status = 500;
403
+ return result;
404
+ }
405
+ // create parametrized config endpoint
406
+ let endpoint: string = mindlineConfig.configEnabledEndpoint();
407
+ let url: URL = new URL(endpoint);
408
+ url.searchParams.append("configurationId", configurationId);
409
+ url.searchParams.append("isEnabled", enabled.toString());
410
+ // create config headers
411
+ const headers = await mindlineDefineHeaders(instance, authorizedUser);
412
+ let options = { method: "PATCH", headers: headers };
413
+ // make config endpoint call
414
+ try {
415
+ if (debug) debugger;
416
+ console.log("Attempting PATCH to /config: " + url.href);
417
+ let response = await fetch(url.href, options);
418
+ if (response.status === 200 && response.statusText === "OK") {
419
+ console.log(`Successful PATCH to ${url.href}: ${enabled.toString()}`);
420
+ return result;
421
+ }
422
+ else {
423
+ result.error = await processErrors(response);
424
+ console.log(`Failed PATCH to ${url.href}: ${enabled.toString()}`);
425
+ console.log(result.error);
426
+ result.status = 500;
427
+ result.result = false;
428
+ return result;
429
+ }
430
+ }
431
+ catch (error: any) {
432
+ result.error = error.message;
433
+ result.status = 500;
434
+ result.result = false;
435
+ console.log(error.message);
436
+ }
437
+ return result;
438
+ }
390
439
  //configPost
391
440
  export async function configPost(
392
441
  instance: IPublicClientApplication,
@@ -489,7 +538,6 @@ export async function configPut(
489
538
  {
490
539
  "name": "${config.name}",
491
540
  "description": "${config.description}",
492
- "isEnabled": ${config.isEnabled},
493
541
  "tenants": [`;
494
542
  config.tenants.map((tci: TenantConfigInfo) => {
495
543
  // if last character is } we need a comma first
package/index.d.ts CHANGED
@@ -22,6 +22,8 @@ declare module "@mindline/sync" {
22
22
  static adminEndpoint(): string;
23
23
  static adminIncompleteEndpoint(): string;
24
24
  static adminsEndpoint(): string;
25
+ static configConsentEndpoint(): string;
26
+ static configEnabledEndpoint(): string;
25
27
  static configEndpoint(): string;
26
28
  static configsEndpoint(): string;
27
29
  static initEndpoint(): string;
@@ -319,15 +321,8 @@ declare module "@mindline/sync" {
319
321
  // ======================= Mindline Config API ===============================
320
322
  export function configConsentForRead(instance: IPublicClientApplication, authorizedUser: User, configId: string, tid: string, consent: boolean): Promise<APIResult>;
321
323
  export function configConsentForWrite(instance: IPublicClientApplication, authorizedUser: User, configId: string, tid: string, consent: boolean): Promise<APIResult>;
322
- export function configEdit(
323
- instance: IPublicClientApplication,
324
- authorizedUser: User,
325
- config: Config,
326
- setConfigId: (id: string) => void,
327
- setSelectedConfigs: (selectedConfigs: { [id: string]: boolean | number[] }) => void,
328
- workspace: Workspace,
329
- ii: InitInfo,
330
- debug: boolean): APIResult;
324
+ export function configEdit(instance: IPublicClientApplication, authorizedUser: User, config: Config, setConfigId: (id: string) => void, setSelectedConfigs: (selectedConfigs: { [id: string]: boolean | number[] }) => void, workspace: Workspace, ii: InitInfo, debug: boolean): APIResult;
325
+ export function configEnable(instance: IPublicClientApplication, authorizedUser: User, configurationId: string, enabled: boolean, debug: boolean): APIResult;
331
326
  export function configRemove(instance: IPublicClientApplication, authorizedUser: User, config: Config, workspaceId: string, debug: boolean): APIResult;
332
327
  export function configsRefresh(instance: IPublicClientApplication, authorizedUser: User, workspaceId: string, ii: InitInfo, debug: boolean): APIResult;
333
328
  export function initGet(instance: IPublicClientApplication, user: User, ii: InitInfo, tasks: TaskArray, debug: boolean): APIResult;
package/index.ts CHANGED
@@ -3,7 +3,7 @@ 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 { processErrors, adminDelete, adminPost, adminsGet, configConsentReadPut, configConsentWritePut, configDelete, configsGet, configPost, configPut, initPost, readerPost, tenantPost, tenantDelete, tenantsGet, workspacePut, workspacesGet } from './hybridspa';
6
+ import { processErrors, adminDelete, adminPost, adminsGet, configConsentReadPut, configConsentWritePut, configDelete, configsGet, configPatch, configPost, configPut, initPost, readerPost, tenantPost, tenantDelete, tenantsGet, workspacePut, workspacesGet } from './hybridspa';
7
7
  import { version } from './package.json';
8
8
  import users from "./users.json";
9
9
  import tenants from "./tenants.json";
@@ -51,6 +51,9 @@ export class mindlineConfig {
51
51
  static configConsentEndpoint(): string {
52
52
  return `https://${mindlineConfig.environmentTag}-configurationapi-westus.azurewebsites.net/api/v1/configuration/consent`;
53
53
  };
54
+ static configEnabledEndpoint(): string {
55
+ return `https://${mindlineConfig.environmentTag}-configurationapi-westus.azurewebsites.net/api/v1/configuration/status`;
56
+ };
54
57
  static configEndpoint(): string {
55
58
  return `https://${mindlineConfig.environmentTag}-configurationapi-westus.azurewebsites.net/api/v1/configuration`;
56
59
  };
@@ -1358,6 +1361,10 @@ export class ActorNode {
1358
1361
  }
1359
1362
  }
1360
1363
  // ======================= Azure AD Graph API ===============================
1364
+ // helper functions
1365
+ function getGraphAPIScope(user: User): string {
1366
+ return "Group.Read.All User.Read.All openid profile offline_access User.Read Contacts.Read CrossTenantInformation.ReadBasic.All";
1367
+ }
1361
1368
  // TODO: this is where you want to trigger a re-authentication if token expires
1362
1369
  async function graphDefineHeaders(
1363
1370
  instance: IPublicClientApplication,
@@ -1366,7 +1373,8 @@ async function graphDefineHeaders(
1366
1373
  const headers = new Headers();
1367
1374
  headers.append("Content-Type", "application/json");
1368
1375
  headers.append("accept", "*/*");
1369
- // authorization header - if needed, retrieve and cache access token
1376
+ const graphAPIScope: string = getGraphAPIScope(user);
1377
+ // only call acquireTokenByCode if we have never redeemed the code
1370
1378
  if (user.graphAccessToken == null || user.graphAccessToken === "") {
1371
1379
  try {
1372
1380
  let response: AuthenticationResult = await instance.acquireTokenByCode({
@@ -1379,6 +1387,47 @@ async function graphDefineHeaders(
1379
1387
  console.log("Front end token failure: " + error);
1380
1388
  }
1381
1389
  }
1390
+ // otherwise, call acquireTokenSilent and deal with token expiration on exception
1391
+ else {
1392
+ try {
1393
+ let accounts: AccountInfo[] = instance.getAllAccounts();
1394
+ let homeAccountId = user.oid + "." + user.tid;
1395
+ let account: AccountInfo = null;
1396
+ for (let i: number = 0; i < accounts.length; i++) {
1397
+ if (accounts[i].homeAccountId == homeAccountId) {
1398
+ account = accounts[i];
1399
+ }
1400
+ }
1401
+ let response: AuthenticationResult = await instance.acquireTokenSilent({
1402
+ scopes: [graphAPIScope],
1403
+ account: account
1404
+ });
1405
+ user.graphAccessToken = response.accessToken; // cache access token
1406
+ console.log("Front end token graph acquired silently: " + user.graphAccessToken.slice(0, 20));
1407
+ }
1408
+ catch (error: any) {
1409
+ try {
1410
+ console.log("Front end graph token silent acquisition failure: " + error);
1411
+ // fallback to redirect if silent acquisition fails
1412
+ let accounts: AccountInfo[] = instance.getAllAccounts();
1413
+ let homeAccountId = user.oid + "." + user.tid;
1414
+ let account: AccountInfo = null;
1415
+ for (let i: number = 0; i < accounts.length; i++) {
1416
+ if (accounts[i].homeAccountId == homeAccountId) {
1417
+ account = accounts[i];
1418
+ }
1419
+ }
1420
+ // assumption: this redirect will trigger login flow callbacks in program.cs
1421
+ instance.acquireTokenRedirect({
1422
+ scopes: [graphAPIScope],
1423
+ account: account
1424
+ });
1425
+ }
1426
+ catch (error: any) {
1427
+ console.log("Front end graph token redirect acquisition failure: " + error);
1428
+ }
1429
+ }
1430
+ }
1382
1431
  headers.append("Authorization", `Bearer ${user.graphAccessToken}`);
1383
1432
  return headers;
1384
1433
  }
@@ -1525,7 +1574,7 @@ export async function signIn(user: User, tasks: TaskArray): Promise<boolean> {
1525
1574
  return false;
1526
1575
  }
1527
1576
  }
1528
- // SignIn by an admin consents the app, Challenge adds incremental permissions dynamically, but requires a consented app - TEST THIS
1577
+ // SignIn by an admin consents the app, Challenge adds incremental permissions dynamically, but requires a consented app - TODO: TEST FRESH CONSENT EXPERIENCE
1529
1578
  let signinURL: string = window.location.href;
1530
1579
  switch (user.authority) {
1531
1580
  case graphConfig.authorityWW:
@@ -1543,11 +1592,17 @@ export async function signIn(user: User, tasks: TaskArray): Promise<boolean> {
1543
1592
  }
1544
1593
  let url: URL = new URL(signinURL);
1545
1594
  url.searchParams.append("redirectUri", window.location.origin);
1546
- url.searchParams.append("domainHint", "organizations");
1547
- // "1" is the OID that is set by default when reading the user objects from the JSON initialization file.
1548
- // This means this user has not been created by the admin. If it had been, oid and mail would be the same and not == "1".
1549
1595
  if (user.oid !== "1") {
1550
1596
  url.searchParams.append("loginHint", user.mail);
1597
+ const regex = /@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/;
1598
+ const regexMatch = user.mail.match(regex);
1599
+ let domain: string = regexMatch ? regexMatch[1] : "organizations";
1600
+ url.searchParams.append("domainHint", domain);
1601
+ }
1602
+ else {
1603
+ // "1" is the dummy OID set when initializing the application from JSON. No need to provide any specific hint.
1604
+ // This means that a user has not yet been specified by the admin. If it had been, oid would not be "1".
1605
+ url.searchParams.append("domainHint", "organizations");
1551
1606
  }
1552
1607
  tasks.setTaskStart("initialization", new Date());
1553
1608
  tasks.setTaskStart("authenticate user", new Date());
@@ -1555,6 +1610,7 @@ export async function signIn(user: User, tasks: TaskArray): Promise<boolean> {
1555
1610
  return true;
1556
1611
  }
1557
1612
  export function signInIncrementally(user: User, scope: string): void {
1613
+ debugger;
1558
1614
  if (user.oid == "1") return;
1559
1615
  // for dynamic delegated permissions, we can use the Microsoft Identity Web Account Controller Challenge method
1560
1616
  let challengeURL: string = window.location.href;
@@ -1653,7 +1709,8 @@ export async function tenantRelationshipsGetByDomain(loggedInUser: User, tenant:
1653
1709
  tenantEndpoint += "')";
1654
1710
  console.log("tenantRelationshipsGetByDomain: Attempting GET from /findTenantInformationByDomainName:", tenantEndpoint);
1655
1711
  let response = await fetch(tenantEndpoint, options);
1656
- if (response.status == 200 && response.statusText == "OK") {
1712
+ // status IS 200, but statusText no longer returns "OK" 1/26/2025
1713
+ if (response.status == 200) { // && response.statusText == "OK") {
1657
1714
  let data = await response.json();
1658
1715
  if (data) {
1659
1716
  if (data.error != null) {
@@ -1913,6 +1970,17 @@ export async function configEdit(
1913
1970
  ii.save();
1914
1971
  return result;
1915
1972
  }
1973
+ export async function configEnable(
1974
+ instance: IPublicClientApplication,
1975
+ authorizedUser: User,
1976
+ configurationId: string,
1977
+ enabled: boolean,
1978
+ debug: boolean
1979
+ ): Promise<APIResult> {
1980
+ let result: APIResult = new APIResult();
1981
+ result = await configPatch(instance, authorizedUser, configurationId, enabled, debug);
1982
+ return result;
1983
+ }
1916
1984
  export async function configRemove(instance: IPublicClientApplication, authorizedUser: User, config: Config, workspaceId: string, debug: boolean): Promise<APIResult> {
1917
1985
  return configDelete(instance, authorizedUser, config, workspaceId, debug);
1918
1986
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mindline/sync",
3
3
  "type": "module",
4
- "version": "1.0.82",
4
+ "version": "1.0.84",
5
5
  "types": "index.d.ts",
6
6
  "exports": "./index.ts",
7
7
  "description": "sync is a node.js package encapsulating javscript classes required for configuring Mindline sync service.",