@mindline/sync 1.0.18 → 1.0.19

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/configs.json CHANGED
@@ -16,6 +16,6 @@
16
16
  "targetGroup": "TODO"
17
17
  }
18
18
  ],
19
- "enabled": "false"
19
+ "enabled": ""
20
20
  }
21
21
  ]
package/hybridspa.ts ADDED
@@ -0,0 +1,159 @@
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");
6
+
7
+ // Add here the endpoints for MS Graph API services you would like to use.
8
+ const graphConfig = {
9
+ graphMeEndpoint: "https://graph.microsoft.com/v1.0/me",
10
+ graphMailEndpoint: "https://graph.microsoft.com/v1.0/me/messages",
11
+ graphTenantEndpoint:
12
+ "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId",
13
+ };
14
+
15
+ function updateUI(data, endpoint) {
16
+ console.log("Graph API responded at: " + new Date().toString());
17
+
18
+ if (endpoint === graphConfig.graphMeEndpoint) {
19
+ profileDiv.innerHTML = "";
20
+ const title = document.createElement("p");
21
+ title.innerHTML = "<strong>Title: </strong>" + data.jobTitle;
22
+ console.log(data.jobTitle);
23
+ const email = document.createElement("p");
24
+ email.innerHTML = "<strong>Mail: </strong>" + data.mail;
25
+ console.log(data.mail);
26
+ const phone = document.createElement("p");
27
+ phone.innerHTML = "<strong>Phone: </strong>" + data.businessPhones[0];
28
+ console.log(data.businessPhones[0]);
29
+ const address = document.createElement("p");
30
+ address.innerHTML = "<strong>Location: </strong>" + data.officeLocation;
31
+ console.log(data.officeLocation);
32
+ profileDiv.appendChild(title);
33
+ profileDiv.appendChild(email);
34
+ profileDiv.appendChild(phone);
35
+ profileDiv.appendChild(address);
36
+ } else if (endpoint === graphConfig.graphMailEndpoint) {
37
+ if (data.value.length < 1) {
38
+ alert("Your mailbox is empty!");
39
+ } else {
40
+ 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
+ data.value.map((d, i) => {
46
+ // Keeping it simple
47
+ 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);
68
+ }
69
+ });
70
+ }
71
+ }
72
+ }
73
+
74
+ // Helper function to call MS Graph API endpoint
75
+ // using authorization bearer token scheme
76
+ function callMSGraph(endpoint, token, callback) {
77
+ const headers = new Headers();
78
+ const bearer = `Bearer ${token}`;
79
+ headers.append("Authorization", bearer);
80
+
81
+ const options = {
82
+ method: "GET",
83
+ headers: headers,
84
+ };
85
+
86
+ console.log("request made to Graph API at: " + new Date().toString());
87
+
88
+ fetch(endpoint, options)
89
+ .then((response) => response.json())
90
+ .then((response) => callback(response, endpoint))
91
+ .then((result) => {
92
+ console.log("Successfully Fetched Data from Graph API:", result);
93
+ })
94
+ .catch((error) => console.log(error));
95
+ }
96
+
97
+ ///get Token
98
+ function getTokenByCode(spaCode) {
99
+ var code = spaCode;
100
+ const scopes = ["user.read"];
101
+
102
+ console.log("MSAL: acquireTokenByCode hybrid parameters present");
103
+
104
+ var authResult = msalInstance.acquireTokenByCode({
105
+ code,
106
+ scopes,
107
+ });
108
+ console.log(authResult);
109
+
110
+ return authResult;
111
+ }
112
+
113
+ //See Profile
114
+ function seeProfile(spaCode) {
115
+ getTokenByCode(spaCode)
116
+ .then((response) => {
117
+ callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
118
+ })
119
+ .catch((error) => {
120
+ console.log(error);
121
+ });
122
+ }
123
+
124
+ //Get Tenant Info
125
+ async function getTenantInfo(user: User, instance: IPublicClientApplication) {
126
+ var authResult = await instance
127
+ .acquireTokenByCode({ code: user.spacode })
128
+ .catch((e: any) => {
129
+ console.log(e);
130
+ });
131
+
132
+ const headers = new Headers();
133
+ const bearer = `Bearer ${authResult.accessToken}`;
134
+ headers.append("Authorization", bearer);
135
+
136
+ const options = {
137
+ method: "GET",
138
+ headers: headers,
139
+ };
140
+
141
+ var tenantEndpoint = graphConfig.graphTenantEndpoint;
142
+ tenantEndpoint += "(tenantId='";
143
+ tenantEndpoint += user.tid;
144
+ tenantEndpoint += "')";
145
+
146
+ console.log(
147
+ "request made to Graph API tenant endpoint at: " + new Date().toString()
148
+ );
149
+
150
+ fetch(tenantEndpoint, options)
151
+ .then((response) => response.json())
152
+ .then((response) => {
153
+ console.log("Successfully Fetched Data from Graph API:", response);
154
+ })
155
+ .catch((error) => console.log(error));
156
+
157
+ user.companyName = response.displayName;
158
+ user.companyDomain = response.defaultDomainName;
159
+ }
package/index.test.ts ADDED
@@ -0,0 +1,16 @@
1
+ import {sum, User, InitInfo, InitGet } from "index";
2
+ import {test, expect} from "vitest";
3
+
4
+ test("adds 1 + 2 to equal 3", () => {
5
+ expect(sum(1, 2)).toBe(3);
6
+ });
7
+ test("loads config based on a user and expects function to return true", () => {
8
+ 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
+ });
15
+ expect(bResult);
16
+ });
@@ -22,6 +22,7 @@ export class User {
22
22
  this.associatedWorkspaces = {};
23
23
  this.workspaceIDs = "";
24
24
  this.session = "";
25
+ this.spacode = "";
25
26
  }
26
27
  }
27
28
 
@@ -118,15 +119,15 @@ export class InitInfo {
118
119
  }
119
120
 
120
121
  import { deserializeArray } from 'class-transformer';
122
+ import { IPublicClientApplication } from '@azure/msal-browser';
121
123
  import users from "./users.json";
122
124
  import targets from "./targets.json";
123
125
  import configs from "./configs.json";
124
126
  import workspaces from "./workspaces.json";
125
127
 
126
- // retrieve Workspace(s), User(s), Target(s), Config(s) given logged in user
127
- export function InitGet(user, ii)
128
+ // get hardcoded data from JSON
129
+ function DummyInit(ii)
128
130
  {
129
- // for now, just get hardcoded data from JSON
130
131
  var usersString = JSON.stringify(users);
131
132
  var targetsString = JSON.stringify(targets);
132
133
  var configsString = JSON.stringify(configs);
@@ -143,6 +144,55 @@ export function InitGet(user, ii)
143
144
  }
144
145
  return true;
145
146
  }
147
+ // retrieve Workspace(s), User(s), Target(s), Config(s) given logged in user
148
+ // three InitGet scenarios
149
+ // scenario 1: empty user array, read defaults
150
+ // scenario 2: user array with dummy user at end, return without doing anything
151
+ // scenario 3: user array with non-dummy user at end, call back end Init
152
+ // (1) TODO: Azure AD: lookup companyDomain and companyName
153
+ // look up tenant name
154
+ // look up tenant domain
155
+ // TODO: Mindline: post complete user to init endpoint
156
+ // create and push partial tenant at end of target array
157
+ // post user and partial tenant to InitInfo
158
+ // Return: success return value, need to query for associations
159
+ // (2) Sync NPM: ii.ws: once InitInfo completes, retrieve workspaces for the new user
160
+ // TODO: Mindline: retrieve associated workspaces
161
+ // Returns: associated workspaces
162
+ // (3) Sync NPM:
163
+ // TODO: Mindline: retrieve associated admins, targets for each workspace
164
+ // ii.us / ii.ts / ii.cs: query components of each associated workspaces
165
+ // Returns: users, targets, configs for each workspace
166
+ export async function InitGet(ii, instance)
167
+ {
168
+ // if empty user array, retrieve dummy data from JSON to populate UI
169
+ let l = ii.us.length;
170
+ if(l === 0) return DummyInit(ii);
171
+
172
+ // if last user is a dummy user, then we have nothing
173
+ let user:User = ii.us[l-1];
174
+ if(user.oid === "1") return true;
175
+
176
+ // have real user: remove dummy user, target, config, workspace if they exist
177
+ let dummyIndex = ii.us.findIndex((u) => u.oid === "1");
178
+ ii.us.splice(dummyIndex, 1);
179
+ dummyIndex = ii.ts.findIndex((u) => u.oid === "1");
180
+ ii.ts.splice(dummyIndex, 1);
181
+ dummyIndex = ii.cs.findIndex((u) => u.oid === "1");
182
+ ii.cs.splice(dummyIndex, 1);
183
+ dummyIndex = ii.ws.findIndex((u) => u.oid === "1");
184
+ ii.ws.splice(dummyIndex, 1);
185
+
186
+ // why would instance be null here? investigate!
187
+ if(instance===null) {
188
+ debugger;
189
+ return false;
190
+ }
191
+
192
+ // valid user, query AAD for associated company name and domain
193
+ getTenantInfo(user, instance);
194
+ return;
195
+ }
146
196
 
147
197
  export function AddTarget()
148
198
  {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mindline/sync",
3
3
  "type": "module",
4
- "version": "1.0.18",
4
+ "version": "1.0.19",
5
5
  "description": "sync is a node.js package encapsulating javscript classes required for configuring Mindline sync service.",
6
6
  "exports": "./index.js",
7
7
  "scripts": {
@@ -15,6 +15,7 @@
15
15
  "vitest": "^0.29.8"
16
16
  },
17
17
  "dependencies": {
18
+ "@azure/msal-browser": "^2.37.0",
18
19
  "class-transformer": "^0.5.1",
19
20
  "reflect-metadata": "^0.1.13"
20
21
  },
package/sync.d.ts CHANGED
@@ -14,6 +14,7 @@ declare module "@mindline/sync" {
14
14
  associatedWorkspaces: string[];
15
15
  workspaceIDs: string;
16
16
  session: string;
17
+ spacode: string;
17
18
  }
18
19
 
19
20
  // target (Azure AD tenant, AD domain, Google workspace)
@@ -61,7 +62,7 @@ declare module "@mindline/sync" {
61
62
  tagWithWorkspaces(): boolean;
62
63
  }
63
64
 
64
- export function InitGet(u: User, ii: InitInfo): boolean;
65
+ export function InitGet(ii: InitInfo, instance: IPublicClientApplication): boolean;
65
66
  export function AddTarget(): boolean;
66
67
  export function CompleteTarget(): boolean;
67
68
  export function AddUser(): boolean;
package/index.test.js DELETED
@@ -1,12 +0,0 @@
1
- import {sum, User, InitInfo, InitGet } from "./index.js";
2
- import {test, expect} from "vitest";
3
-
4
- test("adds 1 + 2 to equal 3", () => {
5
- expect(sum(1, 2)).toBe(3);
6
- });
7
- test("loads config based on a user and expects function to return true", () => {
8
- let u = new User();
9
- let ii = new InitInfo();
10
- expect(InitGet(u, ii)).toBe(true);
11
- expect(ii.us.length).toBe(6);
12
- });