@mindline/sync 1.0.55 → 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,22 +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
- // 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
1233
1243
  let tenantURL: string = window.location.href;
1234
1244
  tenantURL += "MicrosoftIdentity/Account/SignIn";
1235
1245
  let url: URL = new URL(tenantURL);
1236
1246
  url.searchParams.append("redirectUri", window.location.origin);
1237
1247
  url.searchParams.append("domainHint", "organizations");
1238
- 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
1239
1249
  url.searchParams.append("loginHint", user.mail);
1240
1250
  }
1241
1251
  tasks.setTaskStart("initialization", new Date());
1242
1252
  tasks.setTaskStart("authenticate user", new Date());
1243
1253
  window.location.assign(url.href);
1244
- break;
1254
+ return true;
1245
1255
  case graphConfig.authorityUS:
1246
1256
  // retrieve controller protected by USGov authorization
1247
1257
  let usURL: string = window.location.href;
@@ -1255,13 +1265,15 @@ export async function signIn(user: User, tasks: TaskArray): void {
1255
1265
  tasks.setTaskStart("initialization", new Date());
1256
1266
  tasks.setTaskStart("authenticate user", new Date());
1257
1267
  window.location.assign(urlUS.href);
1258
- break;
1268
+ return true;
1259
1269
  case graphConfig.authorityCN:
1260
1270
  // unsupported
1261
1271
  break;
1262
1272
  default:
1273
+ // unknown authority
1263
1274
  debugger;
1264
1275
  }
1276
+ return false;
1265
1277
  }
1266
1278
  export function signInIncrementally(user: User, scope: string): void {
1267
1279
  if (user.oid == "1") return;
@@ -1304,7 +1316,7 @@ export function requestAdminConsent(user: User, scope: string): void {
1304
1316
  window.location.assign(url.href);
1305
1317
  }
1306
1318
  export async function signOut(user: User): Promise<boolean>{
1307
- if (user.oid == "1") return;
1319
+ if (user.oid == "1") return false;
1308
1320
  // set logout_hint in the .NET session for streamlined logout
1309
1321
  let userEndpoint: string = window.location.href;
1310
1322
  userEndpoint += "user";
@@ -1320,7 +1332,7 @@ export async function signOut(user: User): Promise<boolean>{
1320
1332
  }
1321
1333
  else {
1322
1334
  console.log(`Failed to set admin ${user.mail} logout_hint`);
1323
- return;
1335
+ return false;
1324
1336
  }
1325
1337
  // start the logout process triggering callbacks during logout
1326
1338
  // OnRedirectToIdentityProviderForSignOut - this is where we set the logout_hint for user we are trying to logout
@@ -1328,6 +1340,7 @@ export async function signOut(user: User): Promise<boolean>{
1328
1340
  let signoutURL: string = window.location.href;
1329
1341
  signoutURL += "MicrosoftIdentity/Account/SignOut";
1330
1342
  window.location.assign(signoutURL);
1343
+ return true;
1331
1344
  }
1332
1345
  //tenantRelationshipsGetByDomain - query AAD for associated company name and id
1333
1346
  export async function tenantRelationshipsGetByDomain(loggedInUser: User, tenant: Tenant, instance: IPublicClientApplication, debug: boolean): Promise<boolean> {
@@ -1667,6 +1680,17 @@ function processReturnedAdmins(workspace: Workspace, ii: InitInfo, returnedAdmin
1667
1680
  user.name = item.firstName ?? user.name;
1668
1681
  user.mail = item.email;
1669
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
+ }
1670
1694
  // ensure this workspace tracks this user
1671
1695
  let idx = workspace.associatedUsers.findIndex((u) => u === user.oid);
1672
1696
  if (idx == -1) workspace.associatedUsers.push(user.oid);
@@ -1813,9 +1837,9 @@ async function workspaceInfoGet(instance: IPublicClientApplication, authorizedUs
1813
1837
  if (!adminsResult.result) return adminsResult;
1814
1838
  if (!tenantsResult.result) return tenantsResult;
1815
1839
  if (!configsResult.result) return configsResult;
1816
- // process returned workspace components
1817
- processReturnedAdmins(workspace, ii, adminsResult.array!);
1840
+ // process returned workspace components (tenants first as they have the authorities that admins depend on)
1818
1841
  processReturnedTenants(workspace, ii, tenantsResult.array!);
1842
+ processReturnedAdmins(workspace, ii, adminsResult.array!);
1819
1843
  processReturnedConfigs(workspace, ii, configsResult.array!);
1820
1844
  // tag components with workspaceIDs
1821
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.55",
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.",