@mindline/sync 1.0.11 → 1.0.13

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 ADDED
@@ -0,0 +1,21 @@
1
+ [
2
+ {
3
+ "id": "1",
4
+ "name": "ProdSync",
5
+ "description": "Automated sync of users from Mindline1 to Mindline2",
6
+ "targetConfigs":
7
+ [
8
+ {
9
+ "tid": "7f4567b8-f9a9-4ad3-9cb5-ef16a80e5744",
10
+ "sourceGroups": ["TODO"],
11
+ "targetGroup": ""
12
+ },
13
+ {
14
+ "tid": "df9c2e0a-f6fe-43bb-a155-d51f66dffe0e",
15
+ "sourceGroups": [],
16
+ "targetGroup": "TODO"
17
+ }
18
+ ],
19
+ "enabled": "false"
20
+ }
21
+ ]
package/index.js CHANGED
@@ -1,107 +1,201 @@
1
1
  //index.js
2
2
 
3
- // called by unit test
3
+ // called by unit tests
4
4
  export function sum(a, b) {
5
5
  return a + b;
6
6
  }
7
-
8
- // called by simpleclass test app
9
7
  export function helloNpm() {
10
8
  return "hello NPM";
11
9
  }
12
10
 
11
+ const FILTER_FIELD = "WorkspaceIDs";
12
+
13
13
  export class User {
14
14
  constructor(){
15
- this.authority = "";
16
15
  this.oid = "";
17
- this.tid = "";
18
- this.upn = "";
19
16
  this.name = "";
17
+ this.mail = "";
18
+ this.authority = "";
19
+ this.tid = "";
20
+ this.companyName = "";
21
+ this.companyDomain = "";
22
+ this.associatedWorkspaces = {};
20
23
  }
21
24
  }
22
25
 
23
- export class UserConfigInfo {
24
- constructor(){
25
- this.vts = null;
26
- this.sts = null;
27
- this.scs = null;
28
- }
29
- }
30
-
31
- // shared base class of virtual and sync tenants
32
- export class Tenant {
26
+ export class Target {
33
27
  constructor(){
34
- this.authority = "";
35
28
  this.tid = "";
36
29
  this.name = "";
37
30
  this.domain = "";
31
+ this.type = "";
32
+ this.authority = "";
33
+ this.readServicePrincipal = "";
34
+ this.writeServicePrincipal = "";
38
35
  }
39
36
  }
40
37
 
41
- // class for "hub" tenants
42
- export class VirtualTenant extends Tenant {
38
+ export class Config {
43
39
  constructor(){
44
- super();
40
+ this.id = "";
41
+ this.name = "";
45
42
  this.description = "";
43
+ this.targetConfigs = {};
44
+ this.enabled = false;
46
45
  }
47
46
  }
48
47
 
49
- // class for "spoke" tenants
50
- export class SyncTenant extends Tenant {
48
+ export class Workspace {
51
49
  constructor(){
52
- super();
53
- this.tenantType = "";
54
- this.readServicePrincipal = "";
55
- this.writeServicePrincipal = "";
56
- this.virtualTenantID = "";
50
+ this.id = "";
51
+ this.name = "";
52
+ this.associatedUsers = {};
53
+ this.associatedTargets = {};
54
+ this.associatedConfigs = {};
57
55
  }
58
56
  }
59
57
 
60
- // class for sync configuration
61
- export class SyncConfig {
62
- constructor(){
63
- this.enabled = "";
64
- this.virtualTenantID = "";
65
- this.deltaLink = "";
58
+ export class PortalConfigInfo {
59
+ constructor() {
60
+ this.us = {};
61
+ this.ts = {};
62
+ this.cs = {};
63
+ this.ws = {};
64
+ }
65
+ tagWithWorkspaces() {
66
+ // for each Workspace tag associated User, Target, Config with Workspace.id
67
+ for (let workspace of this.ws) {
68
+ // find matching Users to tag with this workspace
69
+ for (let userID of workspace.associatedUsers) {
70
+ let user = this.us.find((currentUser) => currentUser.oid === userID);
71
+ if (user !== undefined) {
72
+ // we found the user
73
+ if (user[FILTER_FIELD] === undefined) {
74
+ // the user does not have the filter field yet
75
+ try {
76
+ user[FILTER_FIELD] = workspace.id;
77
+ } catch (e) {
78
+ debugger;
79
+ return false;
80
+ }
81
+ } else {
82
+ // the user does have the filter field
83
+ user[FILTER_FIELD] += ", ";
84
+ user[FILTER_FIELD] += workspace.id;
85
+ }
86
+ } else {
87
+ // we should not have PCI that does not have Workspace component objects
88
+ debugger;
89
+ return false;
90
+ }
91
+ }
92
+ // find matching Targets to tag with this workspace
93
+ for (let targetID of workspace.associatedTargets) {
94
+ let target = this.ts.find(
95
+ (currentTarget) => currentTarget.tid === targetID
96
+ );
97
+ if (target !== undefined) {
98
+ // we found the target
99
+ if (target[FILTER_FIELD] === undefined) {
100
+ // the target does not have the filter field yet
101
+ try {
102
+ target[FILTER_FIELD] = workspace.id;
103
+ } catch (e) {
104
+ debugger;
105
+ return false;
106
+ }
107
+ } else {
108
+ // the target does have the filter field
109
+ target[FILTER_FIELD] += ", ";
110
+ target[FILTER_FIELD] += workspace.id;
111
+ }
112
+ } else {
113
+ // we should not have PCI that does not have Workspace component objects
114
+ debugger;
115
+ return false;
116
+ }
117
+ }
118
+ // find matching Configs to tag with this workspace
119
+ for (let configID of workspace.associatedConfigs) {
120
+ let config = this.cs.find(
121
+ (currentConfig) => currentConfig.id === configID
122
+ );
123
+ if (config !== undefined) {
124
+ // we found the config
125
+ if (config[FILTER_FIELD] === undefined) {
126
+ // the config does not have the filter field yet
127
+ try {
128
+ config[FILTER_FIELD] = workspace.id;
129
+ } catch (e) {
130
+ debugger;
131
+ return false;
132
+ }
133
+ } else {
134
+ // the config does have the filter field
135
+ config[FILTER_FIELD] += ", ";
136
+ config[FILTER_FIELD] += workspace.id;
137
+ }
138
+ } else {
139
+ // we should not have PCI that does not have Workspace component objects
140
+ debugger;
141
+ return false;
142
+ }
143
+ }
144
+ }
145
+ return true;
66
146
  }
67
147
  }
68
148
 
69
149
  import { deserializeArray } from 'class-transformer';
70
- import virtualTenants from "./virtualTenants.json";
71
- import syncTenants from "./syncTenants.json";
72
- import syncConfigs from "./syncConfigs.json";
73
-
74
- // called by unit test
75
- export function readobjects() {
76
- // convert read JSON to VirtualTenant array
77
- debugger;
78
- let virtuals = null;
79
- var virtualTenantsString = JSON.stringify(virtualTenants);
80
- try {
81
- virtuals = deserializeArray(VirtualTenant, virtualTenantsString);
82
- } catch (e) {
83
- debugger;
84
- return 0;
85
- }
86
- // make some assertion about the data we just read
87
- return virtuals.length;
88
- }
150
+ import users from "./users.json";
151
+ import targets from "./targets.json";
152
+ import configs from "./configs.json";
153
+ import workspaces from "./workspaces.json";
89
154
 
90
- // retrievesync configurations based on passed user information
91
- export function readConfigs(user, userConfigInfo)
155
+ // retrieve Workspace(s), User(s), Target(s), Config(s) given logged in user
156
+ export function InitPortal(user, portalConfigInfo)
92
157
  {
93
158
  debugger;
94
159
  // for now, just get hardcoded data from JSON
95
- var virtualTenantsString = JSON.stringify(virtualTenants);
96
- var syncTenantsString = JSON.stringify(syncTenants);
97
- var syncConfigsString = JSON.stringify(syncConfigs);
160
+ var usersString = JSON.stringify(users);
161
+ var targetsString = JSON.stringify(targets);
162
+ var configsString = JSON.stringify(configs);
163
+ var workspacesString = JSON.stringify(workspaces);
98
164
  try {
99
- userConfigInfo.vts = deserializeArray(VirtualTenant, virtualTenantsString);
100
- userConfigInfo.sts = deserializeArray(SyncTenant, syncTenantsString);
101
- userConfigInfo.scs = deserializeArray(SyncConfig, syncConfigsString);
165
+ portalConfigInfo.us = deserializeArray(User, usersString);
166
+ portalConfigInfo.ts = deserializeArray(Target, targetsString);
167
+ portalConfigInfo.cs = deserializeArray(Config, configsString);
168
+ portalConfigInfo.ws = deserializeArray(Workspace, workspacesString);
169
+ portalConfigInfo.tagWithWorkspaces();
170
+ debugger;
102
171
  } catch (e) {
103
172
  debugger;
104
173
  return false;
105
174
  }
106
175
  return true;
176
+ }
177
+
178
+ export function AddTarget()
179
+ {
180
+ return true;
181
+ }
182
+
183
+ export function CompleteTarget()
184
+ {
185
+ return true;
186
+ }
187
+
188
+ export function AddUser()
189
+ {
190
+ return true;
191
+ }
192
+
193
+ export function CompleteUser()
194
+ {
195
+ return true;
196
+ }
197
+
198
+ export function CreateConfig()
199
+ {
200
+ return true;
107
201
  }
package/index.test.js CHANGED
@@ -1,15 +1,12 @@
1
- import {sum, readobjects, readConfigs, User, UserConfigInfo, VirtualTenant, SyncTenant, SyncConfig} from "./index.js";
1
+ import {sum, User, PortalConfigInfo, InitPortal } from "./index.js";
2
2
  import {test, expect} from "vitest";
3
3
 
4
4
  test("adds 1 + 2 to equal 3", () => {
5
5
  expect(sum(1, 2)).toBe(3);
6
6
  });
7
- test("loads array of VirtualTenants from JSON and expects 2", () => {
8
- expect(readobjects()).toBe(2);
9
- });
10
7
  test("loads config based on a user and expects function to return true", () => {
11
8
  let u = new User();
12
- let uci = new UserConfigInfo();
13
- expect(readConfigs(u, uci)).toBe(true);
14
- expect(uci.vts.length).toBe(2);
9
+ let pci = new PortalConfigInfo();
10
+ expect(InitPortal(u, pci)).toBe(true);
11
+ expect(pci.us.length).toBe(2);
15
12
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mindline/sync",
3
3
  "type": "module",
4
- "version": "1.0.11",
4
+ "version": "1.0.13",
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": {
package/sync.d.ts CHANGED
@@ -2,50 +2,65 @@ declare module "@mindline/sync" {
2
2
  export function sum(a: number, b: number): number;
3
3
  export function helloNpm(): string;
4
4
 
5
- // user information passed to back end
5
+ // admin
6
6
  export class User {
7
- authority: string; // from AAD
8
- oid: string; // from AAD
9
- tid: string; // from AAD
10
- upn: string; // from AAD
11
- name: string; // from AAD
7
+ oid: string; // from AAD ID token
8
+ name: string; // from AAD ID token
9
+ mail: string; // from AAD ID token TODO: preferred_username *may* differ from UPN, may differ from mail
10
+ authority: string; // from AAD auth response - cloud instance login endpoint
11
+ tid: string; // from AAD ID token
12
+ companyName: string; // findTenantInformationByTenantId TODO: process changes to company name
13
+ companyDomain: string; // findTenantInformationByTenantId TODO: process changes to company name
14
+ associatedWorkspaces: string[];
12
15
  }
13
16
 
14
- // configuration information returned by back end
15
- export class UserConfigInfo {
16
- vts: VirtualTenant[];
17
- sts: SyncTenant[];
18
- scs: SyncConfig[];
17
+ // target (Azure AD tenant, AD domain, Google workspace)
18
+ enum TargetType { AAD = 1, AD, Google }
19
+ export class Target {
20
+ tid: string; // from AAD ID token
21
+ name: string; // findTenantInformationByTenantId
22
+ domain: string; // findTenantInformationByTenantId
23
+ type: TargetType; // always AAD for now
24
+ authority: string; // from AAD ID auth response
25
+ readServicePrincipal: string; // from AAD consent
26
+ writeServicePrincipal: string; // from AAD consent
19
27
  }
20
28
 
21
- // shared base class of virtual and sync tenants
22
- export class Tenant {
23
- authority: string; // from AAD
24
- tid: string; // from AAD
25
- name: string; // from AAD: tenant display name
26
- domain: string; // from AAD: tenant default domain
29
+ // config
30
+ export class TargetConfigInfo {
31
+ tid: string; // target identifier
32
+ sourceGroups: string[]; // source groups - we can confiure multiple source groups for reading (*may* slow things down, but less work for admin)
33
+ targetGroup: string; // target group - we only write users to a single target group (complex to fiugure out which users get written to which groups)
27
34
  }
28
-
29
- // class for "hub" tenants
30
- export class VirtualTenant extends Tenant {
31
- description: string; // from DB
35
+ export class Config {
36
+ id: string;
37
+ name: string;
38
+ description: string;
39
+ targetConfigs: TargetConfigInfo[];
40
+ enabled: boolean;
32
41
  }
33
42
 
34
- // class for "spoke" tenants
35
- export class SyncTenant extends Tenant {
36
- tenantType: string; // from DB: AAD | AD | Google -- always AAD for now
37
- readServicePrincipal: string; // from AAD
38
- writeServicePrincipal: string; // from AAD
39
- virtualTenantID: string;
43
+ // class to group Users, Tenants, and Configs
44
+ export class Workspace {
45
+ id: string;
46
+ name: string;
47
+ associatedUsers: string[];
48
+ associatedTargets: string[];
49
+ associatedConfigs: string[];
40
50
  }
41
51
 
42
- // class for sync configuration
43
- export class SyncConfig {
44
- enabled: boolean; // from DB
45
- virtualTenantID: string;
46
- deltaLink: string;
52
+ export class PortalConfigInfo {
53
+ us: User[];
54
+ ts: Target[];
55
+ cs: Config[];
56
+ ws: Workspace[];
57
+ tagWithWorkspaces(): boolean;
47
58
  }
48
59
 
49
- export function readobjects(): number;
50
- export function readConfigs(u: User, uci: UserConfigInfo): boolean;
60
+ export function InitPortal(u: User, pci: PortalConfigInfo): boolean;
61
+ export function AddTarget(): boolean;
62
+ export function CompleteTarget(): boolean;
63
+ export function AddUser(): boolean;
64
+ export function CompleteUser(): boolean;
65
+ export function CreateConfig(): boolean;
51
66
  }
package/targets.json ADDED
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "tid": "7f4567b8-f9a9-4ad3-9cb5-ef16a80e5744",
4
+ "name": "Mindline1",
5
+ "domain": "mindline1.onmicrosoft.com",
6
+ "type": "1",
7
+ "authority": "https://login.microsoftonline.com/common/",
8
+ "readServicePrincipal": "TODO",
9
+ "writeServicePrincipal": "TODO"
10
+ },
11
+ {
12
+ "tid": "df9c2e0a-f6fe-43bb-a155-d51f66dffe0e",
13
+ "name": "Mindline2",
14
+ "domain": "mindline2.onmicrosoft.com",
15
+ "type": "1",
16
+ "authority": "https://login.microsoftonline.com/common/",
17
+ "readServicePrincipal": "TODO",
18
+ "writeServicePrincipal": "TODO"
19
+ }
20
+ ]
package/users.json ADDED
@@ -0,0 +1,22 @@
1
+ [
2
+ {
3
+ "oid": "102bafe7-9e62-4993-b943-2f20c609e5c9",
4
+ "name": "Arvind Suthar",
5
+ "mail": "arvind@mindline1.onmicrosoft.com",
6
+ "authority": "https://login.microsoftonline.com/common/",
7
+ "tid": "7f4567b8-f9a9-4ad3-9cb5-ef16a80e5744",
8
+ "companyName": "Mindline1",
9
+ "companyDomain": "mindline1.onmicrosoft.com",
10
+ "associatedWorkspaces": [ "1" ]
11
+ },
12
+ {
13
+ "oid": "e5a42d0c-4fa5-4a65-8d9b-90f989ecae9b",
14
+ "name": "Arvind Suthar",
15
+ "mail": "arvind@mindline2.onmicrosoft.com",
16
+ "authority": "https://login.microsoftonline.com/common/",
17
+ "tid": "df9c2e0a-f6fe-43bb-a155-d51f66dffe0e",
18
+ "companyName": "Mindline2",
19
+ "companyDomain": "mindline2.onmicrosoft.com",
20
+ "associatedWorkspaces": [ "1" ]
21
+ }
22
+ ]
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "id": "1",
4
+ "name": "Default",
5
+ "associatedUsers": [ "102bafe7-9e62-4993-b943-2f20c609e5c9", "e5a42d0c-4fa5-4a65-8d9b-90f989ecae9b" ],
6
+ "associatedTargets": [ "7f4567b8-f9a9-4ad3-9cb5-ef16a80e5744", "df9c2e0a-f6fe-43bb-a155-d51f66dffe0e" ],
7
+ "associatedConfigs": [ "1" ]
8
+ }
9
+ ]