@mindline/sync 1.0.19 → 1.0.21

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/README.md CHANGED
@@ -10,6 +10,10 @@ https://nodejs.org/en/download
10
10
  npm install class-transformer --save
11
11
  npm install reflect-metadata --save
12
12
  ```
13
+ ## install @azure/msal-browser
14
+ ``` js
15
+ npm install @azure/msal-browser --save
16
+ ```
13
17
  # 2. Latest releases
14
18
  # 3. API references
15
19
  # 4. Unit Test
package/hybridspa.ts CHANGED
@@ -1,8 +1,5 @@
1
- // Select DOM elements to work with
2
- const welcomeDiv = document.getElementById("welcomeMessage");
3
- const cardDiv = document.getElementById("card-div");
4
- const profileButton = document.getElementById("seeProfile");
5
- const profileDiv = document.getElementById("profile-div");
1
+ import { IPublicClientApplication, AuthenticationResult } from '@azure/msal-browser';
2
+ import { User } from '@mindline/sync';
6
3
 
7
4
  // Add here the endpoints for MS Graph API services you would like to use.
8
5
  const graphConfig = {
@@ -16,55 +13,21 @@ function updateUI(data, endpoint) {
16
13
  console.log("Graph API responded at: " + new Date().toString());
17
14
 
18
15
  if (endpoint === graphConfig.graphMeEndpoint) {
19
- profileDiv.innerHTML = "";
20
- const title = document.createElement("p");
21
- title.innerHTML = "<strong>Title: </strong>" + data.jobTitle;
22
16
  console.log(data.jobTitle);
23
- const email = document.createElement("p");
24
- email.innerHTML = "<strong>Mail: </strong>" + data.mail;
25
17
  console.log(data.mail);
26
- const phone = document.createElement("p");
27
- phone.innerHTML = "<strong>Phone: </strong>" + data.businessPhones[0];
28
18
  console.log(data.businessPhones[0]);
29
- const address = document.createElement("p");
30
- address.innerHTML = "<strong>Location: </strong>" + data.officeLocation;
31
19
  console.log(data.officeLocation);
32
- profileDiv.appendChild(title);
33
- profileDiv.appendChild(email);
34
- profileDiv.appendChild(phone);
35
- profileDiv.appendChild(address);
36
20
  } else if (endpoint === graphConfig.graphMailEndpoint) {
37
21
  if (data.value.length < 1) {
38
22
  alert("Your mailbox is empty!");
39
23
  } else {
40
24
  console.log("Displaying Emails for the signed in user.");
41
- const tabList = document.getElementById("list-tab");
42
- tabList.innerHTML = ""; // clear tabList at each readMail call
43
- const tabContent = document.getElementById("nav-tabContent");
44
-
45
25
  data.value.map((d, i) => {
46
26
  // Keeping it simple
47
27
  if (i < 10) {
48
- const listItem = document.createElement("a");
49
- listItem.setAttribute(
50
- "class",
51
- "list-group-item list-group-item-action"
52
- );
53
- listItem.setAttribute("id", "list" + i + "list");
54
- listItem.setAttribute("data-toggle", "list");
55
- listItem.setAttribute("href", "#list" + i);
56
- listItem.setAttribute("role", "tab");
57
- listItem.setAttribute("aria-controls", i);
58
- listItem.innerHTML = d.subject;
59
- tabList.appendChild(listItem);
60
- const contentItem = document.createElement("div");
61
- contentItem.setAttribute("class", "tab-pane fade");
62
- contentItem.setAttribute("id", "list" + i);
63
- contentItem.setAttribute("role", "tabpanel");
64
- contentItem.setAttribute("aria-labelledby", "list" + i + "list");
65
- contentItem.innerHTML =
66
- "<strong> from: " + d.from.emailAddress.address + "</strong>";
67
- tabContent.appendChild(contentItem);
28
+ console.log(data.officeLocation);
29
+ console.log(d.subject);
30
+ console.log(d.from.emailAddress.address);
68
31
  }
69
32
  });
70
33
  }
@@ -95,13 +58,13 @@ function callMSGraph(endpoint, token, callback) {
95
58
  }
96
59
 
97
60
  ///get Token
98
- function getTokenByCode(spaCode) {
61
+ function getTokenByCode(spaCode: string, instance: IPublicClientApplication) {
99
62
  var code = spaCode;
100
63
  const scopes = ["user.read"];
101
64
 
102
65
  console.log("MSAL: acquireTokenByCode hybrid parameters present");
103
66
 
104
- var authResult = msalInstance.acquireTokenByCode({
67
+ var authResult = instance.acquireTokenByCode({
105
68
  code,
106
69
  scopes,
107
70
  });
@@ -111,8 +74,8 @@ function getTokenByCode(spaCode) {
111
74
  }
112
75
 
113
76
  //See Profile
114
- function seeProfile(spaCode) {
115
- getTokenByCode(spaCode)
77
+ function seeProfile(spaCode: string, instance: IPublicClientApplication) {
78
+ getTokenByCode(spaCode, instance)
116
79
  .then((response) => {
117
80
  callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
118
81
  })
@@ -122,13 +85,16 @@ function seeProfile(spaCode) {
122
85
  }
123
86
 
124
87
  //Get Tenant Info
125
- async function getTenantInfo(user: User, instance: IPublicClientApplication) {
126
- var authResult = await instance
88
+ export function getTenantInfo(user: User, instance: IPublicClientApplication) {
89
+ debugger;
90
+
91
+ let authResult: AuthenticationResult;
92
+ instance
127
93
  .acquireTokenByCode({ code: user.spacode })
94
+ .then((result) => (authResult = result))
128
95
  .catch((e: any) => {
129
96
  console.log(e);
130
97
  });
131
-
132
98
  const headers = new Headers();
133
99
  const bearer = `Bearer ${authResult.accessToken}`;
134
100
  headers.append("Authorization", bearer);
@@ -147,13 +113,17 @@ async function getTenantInfo(user: User, instance: IPublicClientApplication) {
147
113
  "request made to Graph API tenant endpoint at: " + new Date().toString()
148
114
  );
149
115
 
116
+ let r = null;
150
117
  fetch(tenantEndpoint, options)
151
118
  .then((response) => response.json())
152
119
  .then((response) => {
120
+ r = response;
153
121
  console.log("Successfully Fetched Data from Graph API:", response);
154
122
  })
155
123
  .catch((error) => console.log(error));
156
124
 
157
- user.companyName = response.displayName;
158
- user.companyDomain = response.defaultDomainName;
125
+ if(r!==null) {
126
+ user.companyName = r.displayName;
127
+ user.companyDomain = r.defaultDomainName;
128
+ }
159
129
  }
@@ -1,3 +1,5 @@
1
+ import { IPublicClientApplication } from "@azure/msal-browser/dist";
2
+
1
3
  declare module "@mindline/sync" {
2
4
  export function sum(a: number, b: number): number;
3
5
  export function helloNpm(): string;
@@ -18,12 +20,11 @@ declare module "@mindline/sync" {
18
20
  }
19
21
 
20
22
  // target (Azure AD tenant, AD domain, Google workspace)
21
- enum TargetType { AAD = 1, AD, Google }
22
23
  export class Target {
23
24
  tid: string; // from AAD ID token
24
25
  name: string; // findTenantInformationByTenantId
25
26
  domain: string; // findTenantInformationByTenantId
26
- type: TargetType; // always AAD for now
27
+ type: string; // always AAD=1 for now
27
28
  authority: string; // from AAD ID auth response
28
29
  readServicePrincipal: string; // from AAD consent
29
30
  writeServicePrincipal: string; // from AAD consent
@@ -33,7 +34,7 @@ declare module "@mindline/sync" {
33
34
  // config
34
35
  export class TargetConfigInfo {
35
36
  tid: string; // target identifier
36
- sourceGroups: string[]; // source groups - we can confiure multiple source groups for reading (*may* slow things down, but less work for admin)
37
+ sourceGroups: string[]; // source groups - we can configure multiple source groups for reading (*may* slow things down, but less work for admin)
37
38
  targetGroup: string; // target group - we only write users to a single target group (complex to fiugure out which users get written to which groups)
38
39
  }
39
40
  export class Config {
package/index.test.ts CHANGED
@@ -1,16 +1,12 @@
1
- import {sum, User, InitInfo, InitGet } from "index";
1
+ import {sum, InitInfo, InitGet} from "./index";
2
2
  import {test, expect} from "vitest";
3
+ import {stubbedPublicClientApplication} from "@azure/msal-browser/dist";
3
4
 
4
5
  test("adds 1 + 2 to equal 3", () => {
5
6
  expect(sum(1, 2)).toBe(3);
6
7
  });
7
8
  test("loads config based on a user and expects function to return true", () => {
8
9
  let ii = new InitInfo();
9
- let bResult:boolean = false;
10
- InitGet(ii, null)
11
- .then((response) => bResult = response)
12
- .catch((e: any) => {
13
- console.log(e);
14
- });
10
+ let bResult:boolean = InitGet(ii, stubbedPublicClientApplication);
15
11
  expect(bResult);
16
12
  });
package/index.ts CHANGED
@@ -1,17 +1,36 @@
1
1
  //index.js
2
2
 
3
+ import { deserializeArray } from 'class-transformer';
4
+ import { IPublicClientApplication } from '@azure/msal-browser';
5
+ import { getTenantInfo } from './hybridspa';
6
+ import users from "./users.json";
7
+ import targets from "./targets.json";
8
+ import configs from "./configs.json";
9
+ import workspaces from "./workspaces.json";
10
+
11
+ const FILTER_FIELD = "workspaceIDs";
12
+
3
13
  // called by unit tests
4
- export function sum(a, b) {
14
+ export function sum(a: number, b: number): number {
5
15
  return a + b;
6
16
  }
7
- export function helloNpm() {
17
+ export function helloNpm() : string {
8
18
  return "hello NPM";
9
19
  }
10
20
 
11
- const FILTER_FIELD = "workspaceIDs";
12
-
13
- export class User {
14
- constructor(){
21
+ class User {
22
+ oid: string;
23
+ name: string;
24
+ mail: string;
25
+ authority: string;
26
+ tid: string;
27
+ companyName: string;
28
+ companyDomain: string;
29
+ associatedWorkspaces: string[];
30
+ workspaceIDs: string;
31
+ session: string;
32
+ spacode: string;
33
+ constructor() {
15
34
  this.oid = "";
16
35
  this.name = "";
17
36
  this.mail = "";
@@ -19,14 +38,22 @@ export class User {
19
38
  this.tid = "";
20
39
  this.companyName = "";
21
40
  this.companyDomain = "";
22
- this.associatedWorkspaces = {};
41
+ this.associatedWorkspaces = new Array();
23
42
  this.workspaceIDs = "";
24
43
  this.session = "";
25
44
  this.spacode = "";
26
45
  }
27
46
  }
28
47
 
29
- export class Target {
48
+ class Target {
49
+ tid: string;
50
+ name: string;
51
+ domain: string;
52
+ type: string;
53
+ authority: string;
54
+ readServicePrincipal: string;
55
+ writeServicePrincipal: string;
56
+ workspaceIDs: string;
30
57
  constructor(){
31
58
  this.tid = "";
32
59
  this.name = "";
@@ -39,35 +66,57 @@ export class Target {
39
66
  }
40
67
  }
41
68
 
42
- export class Config {
69
+ class TargetConfigInfo {
70
+ tid: string;
71
+ sourceGroups: string[];
72
+ targetGroup: string;
73
+ }
74
+
75
+ class Config {
76
+ id: string;
77
+ name: string;
78
+ description: string;
79
+ targetConfigs: TargetConfigInfo[];
80
+ enabled: boolean;
81
+ workspaceIDs: string;
43
82
  constructor(){
44
83
  this.id = "";
45
84
  this.name = "";
46
85
  this.description = "";
47
- this.targetConfigs = {};
86
+ this.targetConfigs = new Array();
48
87
  this.enabled = false;
49
88
  this.workspaceIDs = "";
50
89
  }
51
90
  }
52
91
 
53
- export class Workspace {
92
+ class Workspace {
93
+ id: string;
94
+ name: string;
95
+ associatedUsers: string[];
96
+ associatedTargets: string[];
97
+ associatedConfigs: string[];
54
98
  constructor(){
55
99
  this.id = "";
56
100
  this.name = "";
57
- this.associatedUsers = {};
58
- this.associatedTargets = {};
59
- this.associatedConfigs = {};
101
+ this.associatedUsers = new Array();
102
+ this.associatedTargets = new Array();
103
+ this.associatedConfigs = new Array();
60
104
  }
61
105
  }
62
106
 
63
107
  export class InitInfo {
64
- constructor() {
65
- this.us = {};
66
- this.ts = {};
67
- this.cs = {};
68
- this.ws = {};
108
+ us: User[];
109
+ ts: Target[];
110
+ cs: Config[];
111
+ ws: Workspace[];
112
+ constructor(){
113
+ debugger;
114
+ this.us = new Array();
115
+ this.ts = new Array();
116
+ this.cs = new Array();
117
+ this.ws = new Array();
69
118
  }
70
- initWorkspaceIDs() {
119
+ tagWithWorkspaces(): boolean {
71
120
  // for each Workspace tag associated User, Target, Config with Workspace.id
72
121
  for (let workspace of this.ws) {
73
122
  // find matching Users to tag with this workspace
@@ -118,15 +167,8 @@ export class InitInfo {
118
167
  }
119
168
  }
120
169
 
121
- import { deserializeArray } from 'class-transformer';
122
- import { IPublicClientApplication } from '@azure/msal-browser';
123
- import users from "./users.json";
124
- import targets from "./targets.json";
125
- import configs from "./configs.json";
126
- import workspaces from "./workspaces.json";
127
-
128
170
  // get hardcoded data from JSON
129
- function DummyInit(ii)
171
+ function DummyInit(ii: InitInfo)
130
172
  {
131
173
  var usersString = JSON.stringify(users);
132
174
  var targetsString = JSON.stringify(targets);
@@ -137,7 +179,7 @@ function DummyInit(ii)
137
179
  ii.ts = deserializeArray(Target, targetsString);
138
180
  ii.cs = deserializeArray(Config, configsString);
139
181
  ii.ws = deserializeArray(Workspace, workspacesString);
140
- if(!ii.initWorkspaceIDs()) return false;
182
+ if(!ii.tagWithWorkspaces()) return false;
141
183
  } catch (e) {
142
184
  debugger;
143
185
  return false;
@@ -163,8 +205,10 @@ function DummyInit(ii)
163
205
  // TODO: Mindline: retrieve associated admins, targets for each workspace
164
206
  // ii.us / ii.ts / ii.cs: query components of each associated workspaces
165
207
  // Returns: users, targets, configs for each workspace
166
- export async function InitGet(ii, instance)
208
+ export function InitGet(ii: InitInfo, instance: IPublicClientApplication): boolean
167
209
  {
210
+ debugger;
211
+
168
212
  // if empty user array, retrieve dummy data from JSON to populate UI
169
213
  let l = ii.us.length;
170
214
  if(l === 0) return DummyInit(ii);
@@ -176,11 +220,11 @@ export async function InitGet(ii, instance)
176
220
  // have real user: remove dummy user, target, config, workspace if they exist
177
221
  let dummyIndex = ii.us.findIndex((u) => u.oid === "1");
178
222
  ii.us.splice(dummyIndex, 1);
179
- dummyIndex = ii.ts.findIndex((u) => u.oid === "1");
223
+ dummyIndex = ii.ts.findIndex((u) => u.tid === "1");
180
224
  ii.ts.splice(dummyIndex, 1);
181
- dummyIndex = ii.cs.findIndex((u) => u.oid === "1");
225
+ dummyIndex = ii.cs.findIndex((u) => u.id === "1");
182
226
  ii.cs.splice(dummyIndex, 1);
183
- dummyIndex = ii.ws.findIndex((u) => u.oid === "1");
227
+ dummyIndex = ii.ws.findIndex((u) => u.id === "1");
184
228
  ii.ws.splice(dummyIndex, 1);
185
229
 
186
230
  // why would instance be null here? investigate!
@@ -191,30 +235,30 @@ export async function InitGet(ii, instance)
191
235
 
192
236
  // valid user, query AAD for associated company name and domain
193
237
  getTenantInfo(user, instance);
194
- return;
238
+ return true;
195
239
  }
196
240
 
197
- export function AddTarget()
241
+ function AddTarget(): boolean
198
242
  {
199
243
  return true;
200
244
  }
201
245
 
202
- export function CompleteTarget()
246
+ function CompleteTarget(): boolean
203
247
  {
204
248
  return true;
205
249
  }
206
250
 
207
- export function AddUser()
251
+ function AddUser(): boolean
208
252
  {
209
253
  return true;
210
254
  }
211
255
 
212
- export function CompleteUser()
256
+ function CompleteUser(): boolean
213
257
  {
214
258
  return true;
215
259
  }
216
260
 
217
- export function CreateConfig()
261
+ function CreateConfig(): boolean
218
262
  {
219
263
  return true;
220
264
  }
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@mindline/sync",
3
3
  "type": "module",
4
- "version": "1.0.19",
4
+ "version": "1.0.21",
5
+ "types": "index.d.ts",
6
+ "exports": "./index.ts",
5
7
  "description": "sync is a node.js package encapsulating javscript classes required for configuring Mindline sync service.",
6
- "exports": "./index.js",
7
8
  "scripts": {
8
9
  "test": "vitest",
9
10
  "coverage": "vitest run --coverage"
@@ -18,6 +19,5 @@
18
19
  "@azure/msal-browser": "^2.37.0",
19
20
  "class-transformer": "^0.5.1",
20
21
  "reflect-metadata": "^0.1.13"
21
- },
22
- "typings": "sync.d.ts"
22
+ }
23
23
  }