@mindline/sync 1.0.43 → 1.0.45

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/slnx.sqlite CHANGED
Binary file
Binary file
package/configs.json CHANGED
@@ -5,6 +5,7 @@
5
5
  "name": "",
6
6
  "description": "",
7
7
  "tenants": [],
8
- "isEnabled": true
8
+ "isEnabled": true,
9
+ "sel": true
9
10
  }
10
11
  ]
package/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { IPublicClientApplication } from "@azure/msal-browser";
2
-
3
2
  declare module "@mindline/sync" {
4
3
  export function sum(a: number, b: number): number;
5
4
  export function helloNpm(): string;
@@ -10,6 +9,14 @@ declare module "@mindline/sync" {
10
9
  description: string;
11
10
  }
12
11
  // admin
12
+ export class UserScope {
13
+ group: string;
14
+ value: string;
15
+ consented: boolean;
16
+ expanded: string;
17
+ static compareByValue(a: UserScope, b: UserScope): number;
18
+ static compareByGroup(a: UserScope, b: UserScope): number;
19
+ }
13
20
  export class User {
14
21
  oid: string; // from AAD ID token
15
22
  name: string; // from AAD ID token
@@ -26,6 +33,7 @@ declare module "@mindline/sync" {
26
33
  loginHint: string;
27
34
  scopes: string[];
28
35
  authTS: Date;
36
+ sel: boolean; // selection state
29
37
  constructor();
30
38
  }
31
39
  // tenant (Azure AD tenant, AD domain, Google workspace)
@@ -51,6 +59,7 @@ declare module "@mindline/sync" {
51
59
  onboarded: string; // have we onboarded this tenant? "true" or "false"
52
60
  authority: string; // from AAD ID auth response
53
61
  workspaceIDs: string;
62
+ sel: boolean; // selection state
54
63
  constructor();
55
64
  }
56
65
  // config
@@ -80,6 +89,7 @@ declare module "@mindline/sync" {
80
89
  tenants: TenantConfigInfo[];
81
90
  isEnabled: boolean;
82
91
  workspaceIDs: string;
92
+ sel: boolean; // selection state
83
93
  constructor();
84
94
  }
85
95
  // class to group Users, Tenants, and Configs
@@ -89,9 +99,11 @@ declare module "@mindline/sync" {
89
99
  associatedUsers: string[];
90
100
  associatedTenants: string[];
91
101
  associatedConfigs: string[];
102
+ sel: boolean; // selection state
92
103
  constructor();
93
104
  }
94
105
  export class InitInfo {
106
+ tab: number;
95
107
  us: User[];
96
108
  ts: Tenant[];
97
109
  cs: Config[];
package/index.ts CHANGED
@@ -24,6 +24,18 @@ export class Group {
24
24
  displayName: string;
25
25
  description: string;
26
26
  }
27
+ export class UserScope {
28
+ group: string;
29
+ value: string;
30
+ consented: boolean;
31
+ expanded: string;
32
+ static compareByValue(a: UserScope, b: UserScope): number {
33
+ return a.value.localeCompare(b.value);
34
+ }
35
+ static compareByGroup(a: UserScope, b: UserScope): number {
36
+ return a.group.localeCompare(b.group);
37
+ }
38
+ }
27
39
  export class User {
28
40
  oid: string;
29
41
  name: string;
@@ -40,6 +52,7 @@ export class User {
40
52
  loginHint: string; // to help sign out without prompt
41
53
  scopes: string[]; // to detect if incremental consent has happened
42
54
  authTS: Date; // timestamp user was authenticated
55
+ sel: boolean; // selection state
43
56
  constructor() {
44
57
  this.oid = "";
45
58
  this.name = "";
@@ -56,6 +69,7 @@ export class User {
56
69
  this.loginHint = "";
57
70
  this.scopes = new Array();
58
71
  this.authTS = new Date(0);
72
+ this.sel = false;
59
73
  }
60
74
  }
61
75
  export enum TenantType {
@@ -80,6 +94,7 @@ export class Tenant {
80
94
  onboarded: string;
81
95
  authority: string;
82
96
  workspaceIDs: string;
97
+ sel: boolean; // selection state
83
98
  constructor() {
84
99
  this.tid = "";
85
100
  this.name = "";
@@ -89,6 +104,7 @@ export class Tenant {
89
104
  this.onboarded = "false";
90
105
  this.authority = "";
91
106
  this.workspaceIDs = "";
107
+ this.sel = false;
92
108
  }
93
109
  }
94
110
  function getGraphEndpoint(authority: string): string {
@@ -137,6 +153,7 @@ export class Config {
137
153
  tenants: TenantConfigInfo[];
138
154
  isEnabled: boolean;
139
155
  workspaceIDs: string;
156
+ sel: boolean; // selection state
140
157
  constructor() {
141
158
  this.id = "";
142
159
  this.name = "";
@@ -144,6 +161,7 @@ export class Config {
144
161
  this.tenants = new Array();
145
162
  this.isEnabled = false;
146
163
  this.workspaceIDs = "";
164
+ this.sel = false;
147
165
  }
148
166
  }
149
167
  export class Workspace {
@@ -152,12 +170,14 @@ export class Workspace {
152
170
  associatedUsers: string[];
153
171
  associatedTenants: string[];
154
172
  associatedConfigs: string[];
173
+ sel: boolean; // selection state
155
174
  constructor() {
156
175
  this.id = "";
157
176
  this.name = "";
158
177
  this.associatedUsers = new Array();
159
178
  this.associatedTenants = new Array();
160
179
  this.associatedConfigs = new Array();
180
+ this.sel = false;
161
181
  }
162
182
  }
163
183
  // check for localStorage availability
@@ -188,6 +208,7 @@ function storageAvailable(type) {
188
208
  }
189
209
  }
190
210
  export class InitInfo {
211
+ tab: number;
191
212
  us: User[];
192
213
  ts: Tenant[];
193
214
  cs: Config[];
@@ -205,7 +226,9 @@ export class InitInfo {
205
226
  let initInfoString: string = result;
206
227
  let iiReadFromLocalStorage: InitInfo = JSON.parse(initInfoString);
207
228
  if (iiReadFromLocalStorage.us.length !== 0) {
208
- if (bClearLocalStorage) { localStorage.removeItem("InitInfo"); }
229
+ if (bClearLocalStorage) {
230
+ localStorage.removeItem("InitInfo");
231
+ }
209
232
  else {
210
233
  this.#initFromObjects(iiReadFromLocalStorage);
211
234
  return;
@@ -213,12 +236,13 @@ export class InitInfo {
213
236
  }
214
237
  }
215
238
  }
216
- // if storage unavailable or we were just asked to clear, read from default files to enable usable UI
239
+ // if storage unavailable or we were just asked to clear, read defaults to enable usable UI
217
240
  var usersString = JSON.stringify(users);
218
241
  var tenantsString = JSON.stringify(tenants);
219
242
  var configsString = JSON.stringify(configs);
220
243
  var workspacesString = JSON.stringify(workspaces);
221
244
  try {
245
+ this.tab = 0;
222
246
  this.us = deserializeArray(User, usersString);
223
247
  this.ts = deserializeArray(Tenant, tenantsString);
224
248
  this.cs = deserializeArray(Config, configsString);
@@ -286,20 +310,88 @@ export class InitInfo {
286
310
  return true;
287
311
  }
288
312
  #initFromObjects(ii: InitInfo): void {
289
- // user array is the only one that has a Date that must be re-created on every read
290
- if (typeof ii.us === "undefined") this.us = new Array();
291
- else this.us = ii.us.map((user: User) => { user.authTS = new Date(user.authTS); return user });
292
- if (typeof ii.ts === "undefined") this.ts = new Array();
293
- else this.ts = ii.ts;
294
- if (typeof ii.cs === "undefined") this.cs = new Array();
295
- else this.cs = ii.cs;
296
- if (typeof ii.ws === "undefined") this.ws = new Array();
297
- else this.ws = ii.ws;
313
+ this.tab = ii.tab;
314
+ if (typeof ii.us === "undefined") {
315
+ this.us = new Array<User>();
316
+ }
317
+ else {
318
+ this.us = ii.us.map((user: User) => {
319
+ let newuser: User = new User();
320
+ newuser.oid = user.oid;
321
+ newuser.name = user.name;
322
+ newuser.mail = user.mail;
323
+ newuser.authority = user.authority;
324
+ newuser.tid = user.tid;
325
+ newuser.companyName = user.companyName;
326
+ newuser.companyDomain = user.companyDomain;
327
+ newuser.associatedWorkspaces = user.associatedWorkspaces;
328
+ newuser.workspaceIDs = user.workspaceIDs;
329
+ newuser.session = user.session;
330
+ newuser.spacode = user.spacode;
331
+ newuser.accessToken = user.accessToken;
332
+ newuser.loginHint = user.loginHint;
333
+ newuser.scopes = user.scopes;
334
+ newuser.authTS = new Date(user.authTS);
335
+ newuser.sel = user.sel;
336
+ return newuser
337
+ });
338
+ }
339
+ if (typeof ii.ts === "undefined") {
340
+ this.ts = new Array<Tenant>();
341
+ }
342
+ else {
343
+ this.ts = ii.ts.map((tenant: Tenant) => {
344
+ let newtenant: Tenant = new Tenant();
345
+ newtenant.tid = tenant.tid;
346
+ newtenant.name = tenant.name;
347
+ newtenant.domain = tenant.domain;
348
+ newtenant.tenantType = tenant.tenantType;
349
+ newtenant.permissionType = tenant.permissionType;
350
+ newtenant.onboarded = tenant.onboarded;
351
+ newtenant.authority = tenant.authority;
352
+ newtenant.workspaceIDs = tenant.workspaceIDs;
353
+ newtenant.sel = tenant.sel;
354
+ return newtenant;
355
+ });
356
+ }
357
+ if (typeof ii.cs === "undefined") {
358
+ this.cs = new Array<Config>();
359
+ }
360
+ else {
361
+ this.cs = ii.cs.map((config: Config) => {
362
+ let newconfig: Config = new Config();
363
+ newconfig.id = config.id;
364
+ newconfig.workspaceId = config.workspaceId;
365
+ newconfig.name = config.name;
366
+ newconfig.description = config.description;
367
+ newconfig.tenants = config.tenants;
368
+ newconfig.isEnabled = config.isEnabled;
369
+ newconfig.workspaceIDs = config.workspaceIDs;
370
+ newconfig.sel = config.sel;
371
+ return newconfig;
372
+ });
373
+ }
374
+ if (typeof ii.ws === "undefined") {
375
+ this.ws = new Array<Workspace>();
376
+ }
377
+ else {
378
+ this.ws = ii.ws.map((workspace: Workspace) => {
379
+ let newworkspace: Workspace = new Workspace();
380
+ newworkspace.id = workspace.id;
381
+ newworkspace.name = workspace.name;
382
+ newworkspace.associatedUsers = workspace.associatedUsers;
383
+ newworkspace.associatedTenants = workspace.associatedTenants;
384
+ newworkspace.associatedConfigs = workspace.associatedConfigs;
385
+ newworkspace.sel = workspace.sel;
386
+ return newworkspace;
387
+ });
388
+ }
298
389
  }
299
390
  }
300
391
  export type TaskType = "initialization" |
301
392
  "authenticate user" |
302
393
  "reload React" |
394
+ "PUT tenant" |
303
395
  "GET tenant details" |
304
396
  "POST config init" |
305
397
  "GET workspaces" |
@@ -1093,8 +1185,7 @@ export function signInIncrementally(user: User, scope: string): void {
1093
1185
  tenantURL += "MicrosoftIdentity/Account/Challenge";
1094
1186
  let url: URL = new URL(tenantURL);
1095
1187
  url.searchParams.append("redirectUri", window.location.origin);
1096
- let scopes = scope;
1097
- url.searchParams.append("scope", scopes);
1188
+ url.searchParams.append("scope", scope);
1098
1189
  url.searchParams.append("domainHint", "organizations");
1099
1190
  url.searchParams.append("loginHint", user.mail);
1100
1191
  window.location.assign(url.href);
@@ -1376,7 +1467,7 @@ export async function initGet(instance: IPublicClientApplication, authorizedUser
1376
1467
  tenant.domain = user.tid;
1377
1468
  let bResult: boolean = await tenantUnauthenticatedLookup(tenant, debug);
1378
1469
  if (bResult) {
1379
- // success, we now know instance of this tenant
1470
+ // success, we now know cloud instance where this tenant is provisioned
1380
1471
  user.authority = tenant.authority;
1381
1472
  // do we have a logged in user from the same authority as this newly proposed tenant?
1382
1473
  let loggedInUser: User | undefined = ii.us.find((u: User) => (u.session === "Sign Out" && u.authority === user.authority));
@@ -1395,12 +1486,18 @@ export async function initGet(instance: IPublicClientApplication, authorizedUser
1395
1486
  result = await workspaceInfoGet(instance, authorizedUser, user, ii, debug);
1396
1487
  tasks.setTaskEnd("GET workspaces", new Date(), result.result ? "complete" : "failed");
1397
1488
  }
1398
- if (result.result) result.error = version;
1399
- else console.log("@mindline/sync package version: " + version);
1489
+ // if successful, return true result and the version in the result.error field
1490
+ if (result.result) {
1491
+ result.error = version;
1492
+ }
1493
+ // if failed, output version information to the log
1494
+ else {
1495
+ console.log("@mindline/sync package version: " + version);
1496
+ }
1400
1497
  return result;
1401
1498
  }
1402
1499
  else {
1403
- result.error = `${user.mail} with insufficient privileges to lookup under authority: ${user.authority}.`;
1500
+ result.error = `${user.mail} has insufficient privileges to lookup under authority: ${user.authority}.`;
1404
1501
  result.result = false;
1405
1502
  return result;
1406
1503
  }
@@ -1440,7 +1537,14 @@ function processReturnedAdmins(workspace: Workspace, ii: InitInfo, returnedAdmin
1440
1537
  if (dummyIndex !== -1) {
1441
1538
  // clear and overwrite dummy
1442
1539
  user = ii.us.at(dummyIndex);
1443
- user.associatedWorkspaces.length = 0;
1540
+ // replace dummy User oid "1" with real oid in associatedTenants of all workspaces
1541
+ ii.ws.map((w: Workspace) => {
1542
+ let idx: number = w.associatedUsers.findIndex((oid: string) => oid == "1");
1543
+ if (idx !== -1) {
1544
+ w.associatedUsers.splice(idx, 1);
1545
+ w.associatedUsers.push(item.userId);
1546
+ }
1547
+ });
1444
1548
  }
1445
1549
  else {
1446
1550
  // create and track new user
@@ -1472,6 +1576,14 @@ function processReturnedTenants(workspace: Workspace, ii: InitInfo, returnedTena
1472
1576
  if (dummyIndex !== -1) {
1473
1577
  // clear and overwrite dummy
1474
1578
  tenant = ii.ts.at(dummyIndex);
1579
+ // replace dummy Tenant id "1" with real id in associatedTenants of all workspaces
1580
+ ii.ws.map((w: Workspace) => {
1581
+ let idx: number = w.associatedTenants.findIndex((tid: string) => tid == "1");
1582
+ if (idx !== -1) {
1583
+ w.associatedTenants.splice(idx, 1);
1584
+ w.associatedTenants.push(item.tenantId);
1585
+ }
1586
+ });
1475
1587
  } else {
1476
1588
  // create and track new tenant
1477
1589
  tenant = new Tenant();
@@ -1510,6 +1622,14 @@ function processReturnedConfigs(workspace: Workspace, ii: InitInfo, returnedConf
1510
1622
  if (dummyIndex !== -1) {
1511
1623
  // clear and overwrite dummy
1512
1624
  config = ii.cs.at(dummyIndex);
1625
+ // replace dummy Config id "1" with real id in associatedConfigs of all workspaces
1626
+ ii.ws.map((w: Workspace) => {
1627
+ let idx: number = w.associatedConfigs.findIndex((id: string) => id == "1");
1628
+ if (idx !== -1) {
1629
+ w.associatedConfigs.splice(idx, 1);
1630
+ w.associatedConfigs.push(item.id);
1631
+ }
1632
+ });
1513
1633
  } else {
1514
1634
  // create and track new workspace
1515
1635
  config = new Config();
@@ -1570,9 +1690,11 @@ async function workspaceInfoGet(instance: IPublicClientApplication, authorizedUs
1570
1690
  workspace = ii.ws.at(wsIndex);
1571
1691
  }
1572
1692
  // clear associations as we are about to reset
1573
- workspace.associatedUsers.length = 0;
1574
- workspace.associatedTenants.length = 0;
1575
- workspace.associatedConfigs.length = 0;
1693
+ // IN PROGRESS: do not clear so we can retain selection state
1694
+ //workspace.associatedUsers.length = 0;
1695
+ //workspace.associatedTenants.length = 0;
1696
+ //workspace.associatedConfigs.length = 0;
1697
+ // set id and name based on returned data
1576
1698
  workspace.id = o.id;
1577
1699
  workspace.name = o.name;
1578
1700
  // parallel GET admins, tenants, configs associated with this workspace
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mindline/sync",
3
3
  "type": "module",
4
- "version": "1.0.43",
4
+ "version": "1.0.45",
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.",
package/tenants.json CHANGED
@@ -6,6 +6,7 @@
6
6
  "tenantType": "",
7
7
  "permissionType": "",
8
8
  "onboarded": false,
9
- "authority": ""
9
+ "authority": "",
10
+ "sel": true
10
11
  }
11
12
  ]
package/users.json CHANGED
@@ -8,6 +8,7 @@
8
8
  "companyName": "",
9
9
  "companyDomain": "",
10
10
  "associatedWorkspaces": [ "1" ],
11
- "session": "Sign In"
11
+ "session": "Sign In",
12
+ "sel": true
12
13
  }
13
14
  ]
package/workspaces.json CHANGED
@@ -4,6 +4,7 @@
4
4
  "name": "",
5
5
  "associatedUsers": [ "1" ],
6
6
  "associatedTenants": [ "1" ],
7
- "associatedConfigs": [ "1" ]
7
+ "associatedConfigs": [ "1" ],
8
+ "sel": true
8
9
  }
9
10
  ]