@mindline/sync 1.0.36 → 1.0.38

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": "\\hybridspa.ts",
5
+ "SelectedNode": "\\index.d.ts",
6
6
  "PreviewInSolutionExplorer": false
7
7
  }
package/.vs/slnx.sqlite CHANGED
Binary file
Binary file
package/hybridspa.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  User,
4
4
  Tenant,
5
5
  Config,
6
+ TenantConfigInfo,
6
7
  APIResult
7
8
  } from "./index";
8
9
  import {
@@ -26,6 +27,7 @@ export const graphConfig = {
26
27
  "https://dev-configurationapi-westus.azurewebsites.net/api/v1/configurations",
27
28
  initEndpoint:
28
29
  "https://dev-configurationapi-westus.azurewebsites.net/api/v1/configuration/init",
30
+ readerStartSyncEndpoint: "https://dev-configurationapi-westus.azurewebsites.net/api/v1/startSync",
29
31
  tenantEndpoint:
30
32
  "https://dev-configurationapi-westus.azurewebsites.net/api/v1/tenant",
31
33
  tenantsEndpoint:
@@ -36,14 +38,17 @@ export const graphConfig = {
36
38
  graphGroupsEndpoint: "https://graph.microsoft.com/v1.0/groups",
37
39
  graphMailEndpoint: "https://graph.microsoft.com/v1.0/me/messages",
38
40
  graphMeEndpoint: "https://graph.microsoft.com/v1.0/me",
39
- graphTenantByDomainEndpoint:
40
- "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByDomainName",
41
- graphTenantByIdEndpoint:
42
- "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId",
43
41
  graphUsersEndpoint: "https://graph.microsoft.com/v1.0/users",
44
- // reader endpoint to trigger sync start
45
- readerStartSyncEndpoint: "https://dev-fn-reader-westus.azurewebsites.net/api/startSync/",
46
- readerApiEndpoint: "https://dev-fn-reader-westus.azurewebsites.net/api/lookup/"
42
+ // sovereign cloud tenant info endpoints
43
+ graphTenantByDomainPredicate: "beta/tenantRelationships/findTenantInformationByDomainName",
44
+ graphTenantByIdPredicate: "beta/tenantRelationships/findTenantInformationByTenantId",
45
+ // authority values are based on the well-known OIDC auth endpoints
46
+ authorityWW: "https://login.microsoftonline.com/",
47
+ authorityWWRegex: /^(https:\/\/login\.microsoftonline\.(?:us|com)\/)([\dA-Fa-f]{8}-[\dA-Fa-f]{4}-[\dA-Fa-f]{4}-[\dA-Fa-f]{4}-[\dA-Fa-f]{12})\/oauth2\/authorize$/,
48
+ authorityUS: "https://login.microsoftonline.us/",
49
+ authorityUSRegex: /^(https:\/\/login\.microsoftonline\.(?:us|com)\/)([\dA-Fa-f]{8}-[\dA-Fa-f]{4}-[\dA-Fa-f]{4}-[\dA-Fa-f]{4}-[\dA-Fa-f]{12})\/oauth2\/authorize$/,
50
+ authorityCN: "https://login.partner.microsoftonline.cn/",
51
+ authorityCNRegex: /^(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$/,
47
52
  };
48
53
  // helper functions
49
54
  async function defineHeaders(
@@ -128,7 +133,7 @@ export async function adminDelete(
128
133
  console.log("Attempting DELETE from /admin: " + url!.href);
129
134
  let response = await fetch(url!.href, options);
130
135
  if (response.status === 200 && response.statusText === "OK") {
131
- console.log(`Successful DELETE from //admin: ${url!.href}`);
136
+ console.log(`Successful DELETE from /admin: ${url!.href}`);
132
137
  return result;
133
138
  } else {
134
139
  result.error = await processErrors(response);
@@ -215,20 +220,9 @@ export async function adminPost(
215
220
  workspaceId: string
216
221
  ): Promise<APIResult> {
217
222
  let result: APIResult = new APIResult();
218
- if (
219
- user.mail == null ||
220
- user.mail === "" ||
221
- user.authority == null ||
222
- user.authority === "" ||
223
- user.tid == null ||
224
- user.tid === "" ||
225
- user.companyName == null ||
226
- user.companyName === "" ||
227
- user.companyDomain == null ||
228
- user.companyDomain === ""
229
- ) {
223
+ if (user.mail == "" || user.authority == "" || user.tid === "") {
230
224
  result.result = false;
231
- result.error = "configPost: invalid config ID";
225
+ result.error = "adminPost: invalid argument";
232
226
  result.status = 500;
233
227
  return result;
234
228
  }
@@ -340,13 +334,20 @@ export async function configPost(
340
334
  "isEnabled": ${config.isEnabled},
341
335
  "tenants": [`;
342
336
  config.tenants.map((tci) => {
337
+ // be sure we send null and not "null" in body
338
+ let sourceGroupId: string = tci.sourceGroupId != "" ? `"${tci.sourceGroupId}"` : "null";
339
+ let sourceGroupName: string = tci.sourceGroupName != "" ? `"${tci.sourceGroupName}"` : "null";
340
+ let targetGroupId: string = tci.targetGroupId != "" ? `"${tci.targetGroupId}"` : "null";
341
+ let targetGroupName: string = tci.targetGroupName != "" ? `"${tci.targetGroupName}"` : "null";
343
342
  // if last character is } we need a comma first
344
343
  let needComma: boolean = configBody.slice(-1) === "}";
345
344
  if (needComma) configBody += ",";
346
345
  configBody += `{
347
346
  "tenantId": "${tci.tid}",
348
- "sourceGroupId": "${tci.sourceGroupId}",
349
- "sourceGroupName": "${tci.sourceGroupName}",
347
+ "sourceGroupId": ${sourceGroupId},
348
+ "sourceGroupName": ${sourceGroupName},
349
+ "targetGroupId": ${targetGroupId},
350
+ "targetGroupName": ${targetGroupName},
350
351
  "configurationTenantType": "${tci.configurationTenantType}"
351
352
  }`;
352
353
  });
@@ -409,15 +410,21 @@ export async function configPut(
409
410
  "description": "${config.description}",
410
411
  "isEnabled": ${config.isEnabled},
411
412
  "tenants": [`;
412
- config.tenants.map((tci) => {
413
+ config.tenants.map((tci: TenantConfigInfo) => {
413
414
  // if last character is } we need a comma first
414
415
  let needComma: boolean = configBody.slice(-1) === "}";
415
416
  if (needComma) configBody += ",";
416
- // TODO: more sophisticated source tenant user filtering
417
+ // be sure we send null and not "null" in body
418
+ let sourceGroupId: string = tci.sourceGroupId != "" ? `"${tci.sourceGroupId}"` : "null";
419
+ let sourceGroupName: string = tci.sourceGroupName != "" ? `"${tci.sourceGroupName}"` : "null";
420
+ let targetGroupId: string = tci.targetGroupId != "" ? `"${tci.targetGroupId}"` : "null";
421
+ let targetGroupName: string = tci.targetGroupName != "" ? `"${tci.targetGroupName}"` : "null";
417
422
  configBody += `{
418
423
  "tenantId": "${tci.tid}",
419
- "sourceGroupId": "${tci.sourceGroupId}",
420
- "sourceGroupName": "${tci.sourceGroupName}",
424
+ "sourceGroupId": ${sourceGroupId},
425
+ "sourceGroupName": ${sourceGroupName},
426
+ "targetGroupId": ${targetGroupId},
427
+ "targetGroupName": ${targetGroupName},
421
428
  "configurationTenantType": "${tci.configurationTenantType}",
422
429
  "deltaToken": "${tci.deltaToken}"
423
430
  }`;
@@ -862,21 +869,21 @@ export async function readerPost(
862
869
  result.status = 500;
863
870
  return result;
864
871
  }
865
- // create reader endpoint with config ID
866
- let readerEndpoint: string = graphConfig.readerStartSyncEndpoint + config.id;
872
+ // create reader endpoint
873
+ let readerEndpoint: string = graphConfig.readerStartSyncEndpoint;
874
+ let url: URL = new URL(readerEndpoint);
875
+ url.searchParams.append("configurationId", config.id);
867
876
  // create headers
868
877
  const headers = await defineHeaders(instance, authorizedUser);
869
878
  // make reader endpoint call
870
879
  let options = { method: "POST", headers: headers };
871
880
  try {
872
- console.log("Attempting POST to /startSync: " + readerEndpoint);
873
- let response = await fetch(readerEndpoint, options);
881
+ console.log("Attempting POST to /startSync: " + url.href);
882
+ let response = await fetch(url.href, options);
874
883
  if (response.status === 200 && response.statusText === "OK") {
875
884
  console.log(`Successful POST to /startSync: ${readerEndpoint}`);
876
-
877
- let textResponse = await response.text();
878
- textResponse = textResponse;
879
-
885
+ let jsonResponse = await response.json();
886
+ result.array = JSON.parse(jsonResponse.PayloadStr);
880
887
  return result;
881
888
  } else {
882
889
  result.error = await processErrors(response);
package/index.d.ts CHANGED
@@ -65,11 +65,14 @@ declare module "@mindline/sync" {
65
65
  export class TenantConfigInfo {
66
66
  tid: string; // tenant identifier
67
67
  sourceGroupId: string; // source group - we can configure source group for reading
68
- sourceGroupName: string; // source group - we can configure source group for reading
68
+ sourceGroupName: string; //
69
+ targetGroupId: string; // target group - we can configure target group for writing
70
+ targetGroupName: string; //
69
71
  configurationTenantType: TenantConfigTypeStrings;
70
72
  deltaToken: string;
71
- filesWritten: number;
73
+ usersWritten: number;
72
74
  configId: string;
75
+ batchId: string;
73
76
  }
74
77
  export class Config {
75
78
  id: string;
@@ -134,18 +137,70 @@ declare module "@mindline/sync" {
134
137
  setEnd(endDate: Date): void;
135
138
  setStart(startDate: Date): void;
136
139
  }
140
+ export class Milestone {
141
+ Run: number;
142
+ Start: Date;
143
+ startDisplay: string;
144
+ POST: Date;
145
+ postDisplay: string;
146
+ Read: Date;
147
+ readDisplay: string;
148
+ Write: Date;
149
+ writeDisplay: string;
150
+ Duration: Date;
151
+ durationDisplay: string;
152
+ constructor(run: number);
153
+ start(start: string): void;
154
+ post(post: string): void;
155
+ read(read: string): void;
156
+ write(write: string): void;
157
+ }
158
+ export class MilestoneArray {
159
+ milestones: Milestone[];
160
+ constructor(bClearLocalStorage: boolean);
161
+ init(bClearLocalStorage: boolean): void;
162
+ save(): void;
163
+ start(setMilestones): void;
164
+ unstart(setMilestones): void;
165
+ post(setMilestones): void;
166
+ read(setMilestones): void;
167
+ write(setMilestones): void;
168
+ #initFromObjects(milestones: Milestones): void;
169
+ }
137
170
  export class BatchArray {
138
171
  tenantNodes: TenantNode[];
172
+ pb_startTS: number;
173
+ pb_progress: number;
174
+ pb_increment: number;
175
+ pb_idle: number;
176
+ pb_idleMax: number;
177
+ pb_timer;
178
+ milestoneArray: MilestoneArray;
139
179
  constructor(config: Config|null, syncPortalGlobalState: InitInfo|null, bClearLocalStorage: boolean);
140
180
  // populate tenantNodes based on config tenants
141
- init(config: Config|null, syncPortalGlobalState: InitInfo|null, bClearLocalStorage: boolean): void;
142
- startSync(instance: IPublicClientApplication, authorizedUser: User|null|undefined, config: Config|null|undefined): void;
181
+ init(config: Config|null|undefined, syncPortalGlobalState: InitInfo|null, bClearLocalStorage: boolean): void;
182
+ initializeProgressBar(setSyncProgress, setConfigSyncResult, setIdleText, setMilestones): void;
183
+ uninitializeProgressBar(setSyncProgress, setConfigSyncResult, setIdleText, setMilestones): void;
184
+ initializeSignalR(
185
+ config: Config | null | undefined,
186
+ syncPortalGlobalState: InitInfo | null,
187
+ batchIdArray: Array<Object>,
188
+ setRefreshDeltaTrigger,
189
+ setReadersTotal,
190
+ setReadersCurrent,
191
+ setWritersTotal,
192
+ setWritersCurrent,
193
+ setMilestones,
194
+ setConfigSyncResult,
195
+ bClearLocalStorage: boolean): void;
196
+ startSync(instance: IPublicClientApplication, authorizedUser: User | null | undefined, config: Config | null | undefined): APIResult;
143
197
  }
144
198
  export class TenantNode {
145
199
  expanded: boolean;
146
200
  status: string;
147
201
  name: string;
148
202
  tid: string;
203
+ batchId: string;
149
204
  total: number;
150
205
  read: number;
151
206
  written: number;
@@ -158,6 +213,7 @@ declare module "@mindline/sync" {
158
213
  result: boolean;
159
214
  status: number;
160
215
  error: string;
216
+ array: Array<Object> | null;
161
217
  constructor();
162
218
  }
163
219
  //
@@ -170,7 +226,8 @@ declare module "@mindline/sync" {
170
226
  export function signOut(user: User): void;
171
227
  export function tenantRelationshipsGetByDomain(loggedInuser: User, tenant: Tenant, instance: IPublicClientApplication, debug: boolean): boolean;
172
228
  export function tenantRelationshipsGetById(user: User, ii: InitInfo, instance: IPublicClientApplication, tasks: TaskArray, debug: boolean): boolean;
173
- export function usersGet(tenant: Tenant): {users: string[], error: string};
229
+ export function tenantUnauthenticatedLookup(tenant: Tenant, debug: boolean): Promise<boolean>;
230
+ export function usersGet(tenant: Tenant): { users: string[], error: string };
174
231
  //
175
232
  // Mindline Config API
176
233
  //