@mindline/sync 1.0.54 → 1.0.56

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/index.d.ts CHANGED
@@ -263,7 +263,7 @@ declare module "@mindline/sync" {
263
263
  // Azure AD Graph API
264
264
  //
265
265
  export function groupsGet(instance: IPublicClientApplication, user: User | undefined, groupSearchString: string): Promise<{groups: Group[], error: string}>;
266
- export function signIn(user: User, tasks: TaskArray): void;
266
+ export function signIn(user: User, tasks: TaskArray): boolean;
267
267
  export function signInIncrementally(user: User, scope: string): void;
268
268
  export function requestAdminConsent(user: User, scope: string): void;
269
269
  export function signOut(user: User): boolean;
package/index.ts CHANGED
@@ -337,14 +337,11 @@ export class InitInfo {
337
337
  } else {
338
338
  // we should not have InitInfo missing Workspace components
339
339
  debugger;
340
- return false;
341
340
  }
342
341
  }
343
342
  // find matching Tenants to tag with this workspace
344
343
  for (let tenantID of workspace.associatedTenants) {
345
- let tenant = this.ts.find(
346
- (currentTenant) => currentTenant.tid === tenantID
347
- );
344
+ let tenant = this.ts.find((currentTenant) => currentTenant.tid === tenantID);
348
345
  if (tenant !== undefined) {
349
346
  // we found the tenant
350
347
  tenant[FILTER_FIELD] += workspace.id;
@@ -352,14 +349,11 @@ export class InitInfo {
352
349
  } else {
353
350
  // we should not have InitInfo missing Workspace components
354
351
  debugger;
355
- return false;
356
352
  }
357
353
  }
358
354
  // find matching Configs to tag with this workspace
359
355
  for (let configID of workspace.associatedConfigs) {
360
- let config = this.cs.find(
361
- (currentConfig) => currentConfig.id === configID
362
- );
356
+ let config = this.cs.find((currentConfig) => currentConfig.id === configID);
363
357
  if (config !== undefined) {
364
358
  // we found the config
365
359
  config[FILTER_FIELD] += workspace.id;
@@ -367,7 +361,6 @@ export class InitInfo {
367
361
  } else {
368
362
  // we should not have InitInfo missing Workspace components
369
363
  debugger;
370
- return false;
371
364
  }
372
365
  }
373
366
  }
@@ -1226,23 +1219,39 @@ export async function groupsGet(instance: IPublicClientApplication, user: User |
1226
1219
  return { groups: [], error: `Exception: ${error}` };
1227
1220
  }
1228
1221
  }
1229
- export async function signIn(user: User, tasks: TaskArray): void {
1222
+ export async function signIn(user: User, tasks: TaskArray): Promise<boolean> {
1223
+ // admin authority is blank at signIn, lookup authority real-time
1224
+ if (user.authority == "") {
1225
+ debugger;
1226
+ // lookup authority for this user (the lookup call does it based on domain, but TID works as well to find authority)
1227
+ let tenant: Tenant = new Tenant();
1228
+ tenant.domain = user.tid;
1229
+ let bResult: boolean = await tenantUnauthenticatedLookup(tenant, false);
1230
+ if (bResult) {
1231
+ // success, we now know cloud instance where this tenant is provisioned
1232
+ user.authority = tenant.authority;
1233
+ }
1234
+ else {
1235
+ // can't sign in without an authority
1236
+ debugger;
1237
+ return false;
1238
+ }
1239
+ }
1230
1240
  switch (user.authority) {
1231
1241
  case graphConfig.authorityWW:
1232
- case "":
1233
- // SignIn by an admin consents more permissions than Challenge which requires a consented app
1242
+ // SignIn by an admin consents the app, Challenge adds incremental permissions dynamicalyy, but requires a consented app
1234
1243
  let tenantURL: string = window.location.href;
1235
1244
  tenantURL += "MicrosoftIdentity/Account/SignIn";
1236
1245
  let url: URL = new URL(tenantURL);
1237
1246
  url.searchParams.append("redirectUri", window.location.origin);
1238
1247
  url.searchParams.append("domainHint", "organizations");
1239
- if (user.oid !== "1") {
1248
+ if (user.oid !== "1") { // "1" means no mail has been set by admin initially in the app, oid and mail should be same if user has set and not yet signed in
1240
1249
  url.searchParams.append("loginHint", user.mail);
1241
1250
  }
1242
1251
  tasks.setTaskStart("initialization", new Date());
1243
1252
  tasks.setTaskStart("authenticate user", new Date());
1244
1253
  window.location.assign(url.href);
1245
- break;
1254
+ return true;
1246
1255
  case graphConfig.authorityUS:
1247
1256
  // retrieve controller protected by USGov authorization
1248
1257
  let usURL: string = window.location.href;
@@ -1256,13 +1265,15 @@ export async function signIn(user: User, tasks: TaskArray): void {
1256
1265
  tasks.setTaskStart("initialization", new Date());
1257
1266
  tasks.setTaskStart("authenticate user", new Date());
1258
1267
  window.location.assign(urlUS.href);
1259
- break;
1268
+ return true;
1260
1269
  case graphConfig.authorityCN:
1261
1270
  // unsupported
1262
1271
  break;
1263
1272
  default:
1273
+ // unknown authority
1264
1274
  debugger;
1265
1275
  }
1276
+ return false;
1266
1277
  }
1267
1278
  export function signInIncrementally(user: User, scope: string): void {
1268
1279
  if (user.oid == "1") return;
@@ -1305,7 +1316,7 @@ export function requestAdminConsent(user: User, scope: string): void {
1305
1316
  window.location.assign(url.href);
1306
1317
  }
1307
1318
  export async function signOut(user: User): Promise<boolean>{
1308
- if (user.oid == "1") return;
1319
+ if (user.oid == "1") return false;
1309
1320
  // set logout_hint in the .NET session for streamlined logout
1310
1321
  let userEndpoint: string = window.location.href;
1311
1322
  userEndpoint += "user";
@@ -1321,7 +1332,7 @@ export async function signOut(user: User): Promise<boolean>{
1321
1332
  }
1322
1333
  else {
1323
1334
  console.log(`Failed to set admin ${user.mail} logout_hint`);
1324
- return;
1335
+ return false;
1325
1336
  }
1326
1337
  // start the logout process triggering callbacks during logout
1327
1338
  // OnRedirectToIdentityProviderForSignOut - this is where we set the logout_hint for user we are trying to logout
@@ -1329,6 +1340,7 @@ export async function signOut(user: User): Promise<boolean>{
1329
1340
  let signoutURL: string = window.location.href;
1330
1341
  signoutURL += "MicrosoftIdentity/Account/SignOut";
1331
1342
  window.location.assign(signoutURL);
1343
+ return true;
1332
1344
  }
1333
1345
  //tenantRelationshipsGetByDomain - query AAD for associated company name and id
1334
1346
  export async function tenantRelationshipsGetByDomain(loggedInUser: User, tenant: Tenant, instance: IPublicClientApplication, debug: boolean): Promise<boolean> {
@@ -1668,6 +1680,17 @@ function processReturnedAdmins(workspace: Workspace, ii: InitInfo, returnedAdmin
1668
1680
  user.name = item.firstName ?? user.name;
1669
1681
  user.mail = item.email;
1670
1682
  user.tid = item.tenantId;
1683
+ // *try* to set authority from tenant returned in previous call processReturnedTenants (it may not be there)
1684
+ // ASSUMPTION: user either comes from
1685
+ // 1. .NET session, in which case user has an authority from the token
1686
+ // 2. Config API, in which case either
1687
+ // 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)
1688
+ // b. user has never logged in (i.e. workspace owner has invited an incomplete admin to the workspace and there is no corresponding tenant)
1689
+ // i. this means that we *may* not have an authority stored for this user
1690
+ let tenant: Tenant | undefined = ii.ts.find((t) => (t.tid === user.tid));
1691
+ if (tenant != undefined) {
1692
+ user.authority = tenant.authority;
1693
+ }
1671
1694
  // ensure this workspace tracks this user
1672
1695
  let idx = workspace.associatedUsers.findIndex((u) => u === user.oid);
1673
1696
  if (idx == -1) workspace.associatedUsers.push(user.oid);
@@ -1814,9 +1837,9 @@ async function workspaceInfoGet(instance: IPublicClientApplication, authorizedUs
1814
1837
  if (!adminsResult.result) return adminsResult;
1815
1838
  if (!tenantsResult.result) return tenantsResult;
1816
1839
  if (!configsResult.result) return configsResult;
1817
- // process returned workspace components
1818
- processReturnedAdmins(workspace, ii, adminsResult.array!);
1840
+ // process returned workspace components (tenants first as they have the authorities that admins depend on)
1819
1841
  processReturnedTenants(workspace, ii, tenantsResult.array!);
1842
+ processReturnedAdmins(workspace, ii, adminsResult.array!);
1820
1843
  processReturnedConfigs(workspace, ii, configsResult.array!);
1821
1844
  // tag components with workspaceIDs
1822
1845
  ii.tagWithWorkspaces();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mindline/sync",
3
3
  "type": "module",
4
- "version": "1.0.54",
4
+ "version": "1.0.56",
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.",