@boxyhq/saml-jackson 1.1.6 → 1.2.0

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.
Files changed (34) hide show
  1. package/dist/controller/error.d.ts +5 -0
  2. package/dist/controller/error.js +6 -1
  3. package/dist/controller/utils.d.ts +13 -0
  4. package/dist/controller/utils.js +27 -1
  5. package/dist/db/mem.js +7 -3
  6. package/dist/directory-sync/Base.d.ts +15 -0
  7. package/dist/directory-sync/Base.js +39 -0
  8. package/dist/directory-sync/DirectoryConfig.d.ts +43 -0
  9. package/dist/directory-sync/DirectoryConfig.js +186 -0
  10. package/dist/directory-sync/DirectoryGroups.d.ts +26 -0
  11. package/dist/directory-sync/DirectoryGroups.js +254 -0
  12. package/dist/directory-sync/DirectoryUsers.d.ts +22 -0
  13. package/dist/directory-sync/DirectoryUsers.js +175 -0
  14. package/dist/directory-sync/Groups.d.ts +47 -0
  15. package/dist/directory-sync/Groups.js +195 -0
  16. package/dist/directory-sync/Users.d.ts +47 -0
  17. package/dist/directory-sync/Users.js +135 -0
  18. package/dist/directory-sync/WebhookEventsLogger.d.ts +13 -0
  19. package/dist/directory-sync/WebhookEventsLogger.js +57 -0
  20. package/dist/directory-sync/events.d.ts +7 -0
  21. package/dist/directory-sync/events.js +53 -0
  22. package/dist/directory-sync/index.d.ts +6 -0
  23. package/dist/directory-sync/index.js +42 -0
  24. package/dist/directory-sync/request.d.ts +7 -0
  25. package/dist/directory-sync/request.js +30 -0
  26. package/dist/directory-sync/transform.d.ts +7 -0
  27. package/dist/directory-sync/transform.js +26 -0
  28. package/dist/directory-sync/utils.d.ts +39 -0
  29. package/dist/directory-sync/utils.js +140 -0
  30. package/dist/index.d.ts +2 -1
  31. package/dist/index.js +7 -3
  32. package/dist/typings.d.ts +275 -7
  33. package/dist/typings.js +9 -0
  34. package/package.json +3 -1
@@ -0,0 +1,47 @@
1
+ import type { User, DatabaseStore, ApiError } from '../typings';
2
+ import { Base } from './Base';
3
+ export declare class Users extends Base {
4
+ constructor({ db }: {
5
+ db: DatabaseStore;
6
+ });
7
+ create(param: {
8
+ first_name: string;
9
+ last_name: string;
10
+ email: string;
11
+ active: boolean;
12
+ raw: any;
13
+ }): Promise<{
14
+ data: User | null;
15
+ error: ApiError | null;
16
+ }>;
17
+ get(id: string): Promise<{
18
+ data: User | null;
19
+ error: ApiError | null;
20
+ }>;
21
+ update(id: string, param: {
22
+ first_name: string;
23
+ last_name: string;
24
+ email: string;
25
+ active: boolean;
26
+ raw: object;
27
+ }): Promise<{
28
+ data: User | null;
29
+ error: ApiError | null;
30
+ }>;
31
+ delete(id: string): Promise<{
32
+ data: null;
33
+ error: ApiError | null;
34
+ }>;
35
+ list({ pageOffset, pageLimit, }: {
36
+ pageOffset?: number;
37
+ pageLimit?: number;
38
+ }): Promise<{
39
+ data: User[] | null;
40
+ error: ApiError | null;
41
+ }>;
42
+ search(userName: string): Promise<{
43
+ data: User[] | null;
44
+ error: ApiError | null;
45
+ }>;
46
+ clear(): Promise<void>;
47
+ }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Users = void 0;
13
+ const error_1 = require("../controller/error");
14
+ const Base_1 = require("./Base");
15
+ class Users extends Base_1.Base {
16
+ constructor({ db }) {
17
+ super({ db });
18
+ }
19
+ // Create a new user
20
+ create(param) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ try {
23
+ const { first_name, last_name, email, active, raw } = param;
24
+ const id = this.createId();
25
+ raw['id'] = id;
26
+ const user = {
27
+ id,
28
+ first_name,
29
+ last_name,
30
+ email,
31
+ active,
32
+ raw,
33
+ };
34
+ yield this.store('users').put(id, user, {
35
+ name: 'userName',
36
+ value: email,
37
+ });
38
+ return { data: user, error: null };
39
+ }
40
+ catch (err) {
41
+ return (0, error_1.apiError)(err);
42
+ }
43
+ });
44
+ }
45
+ // Get a user by id
46
+ get(id) {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ try {
49
+ const user = yield this.store('users').get(id);
50
+ if (user === null) {
51
+ throw new error_1.JacksonError('User not found', 404);
52
+ }
53
+ return { data: user, error: null };
54
+ }
55
+ catch (err) {
56
+ return (0, error_1.apiError)(err);
57
+ }
58
+ });
59
+ }
60
+ // Update the user data
61
+ update(id, param) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ try {
64
+ const { first_name, last_name, email, active, raw } = param;
65
+ raw['id'] = id;
66
+ const user = {
67
+ id,
68
+ first_name,
69
+ last_name,
70
+ email,
71
+ active,
72
+ raw,
73
+ };
74
+ yield this.store('users').put(id, user);
75
+ return { data: user, error: null };
76
+ }
77
+ catch (err) {
78
+ return (0, error_1.apiError)(err);
79
+ }
80
+ });
81
+ }
82
+ // Delete a user by id
83
+ delete(id) {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ try {
86
+ const { data, error } = yield this.get(id);
87
+ if (error || !data) {
88
+ throw error;
89
+ }
90
+ yield this.store('users').delete(id);
91
+ return { data: null, error: null };
92
+ }
93
+ catch (err) {
94
+ return (0, error_1.apiError)(err);
95
+ }
96
+ });
97
+ }
98
+ // Get all users in a directory
99
+ list({ pageOffset, pageLimit, }) {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ try {
102
+ const users = (yield this.store('users').getAll(pageOffset, pageLimit));
103
+ return { data: users, error: null };
104
+ }
105
+ catch (err) {
106
+ return (0, error_1.apiError)(err);
107
+ }
108
+ });
109
+ }
110
+ // Search users by userName
111
+ search(userName) {
112
+ return __awaiter(this, void 0, void 0, function* () {
113
+ try {
114
+ const users = (yield this.store('users').getByIndex({ name: 'userName', value: userName }));
115
+ return { data: users, error: null };
116
+ }
117
+ catch (err) {
118
+ return (0, error_1.apiError)(err);
119
+ }
120
+ });
121
+ }
122
+ // Clear all the users
123
+ clear() {
124
+ return __awaiter(this, void 0, void 0, function* () {
125
+ const { data: users, error } = yield this.list({});
126
+ if (!users || error) {
127
+ return;
128
+ }
129
+ yield Promise.all(users.map((user) => __awaiter(this, void 0, void 0, function* () {
130
+ return this.delete(user.id);
131
+ })));
132
+ });
133
+ }
134
+ }
135
+ exports.Users = Users;
@@ -0,0 +1,13 @@
1
+ import type { Directory, DatabaseStore, WebhookEventLog, DirectorySyncEvent, IWebhookEventsLogger } from '../typings';
2
+ import { Base } from './Base';
3
+ export declare class WebhookEventsLogger extends Base implements IWebhookEventsLogger {
4
+ constructor({ db }: {
5
+ db: DatabaseStore;
6
+ });
7
+ log(directory: Directory, event: DirectorySyncEvent): Promise<WebhookEventLog>;
8
+ get(id: string): Promise<WebhookEventLog>;
9
+ getAll(): Promise<WebhookEventLog[]>;
10
+ delete(id: string): Promise<void>;
11
+ clear(): Promise<void>;
12
+ updateStatus(log: WebhookEventLog, statusCode: number): Promise<WebhookEventLog>;
13
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.WebhookEventsLogger = void 0;
13
+ const Base_1 = require("./Base");
14
+ class WebhookEventsLogger extends Base_1.Base {
15
+ constructor({ db }) {
16
+ super({ db });
17
+ }
18
+ log(directory, event) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const id = this.createId();
21
+ const log = Object.assign(Object.assign({}, event), { id, webhook_endpoint: directory.webhook.endpoint, created_at: new Date() });
22
+ yield this.store('logs').put(id, log);
23
+ return log;
24
+ });
25
+ }
26
+ get(id) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ return yield this.store('logs').get(id);
29
+ });
30
+ }
31
+ getAll() {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ return (yield this.store('logs').getAll());
34
+ });
35
+ }
36
+ delete(id) {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ yield this.store('logs').delete(id);
39
+ });
40
+ }
41
+ clear() {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ const events = yield this.getAll();
44
+ yield Promise.all(events.map((event) => __awaiter(this, void 0, void 0, function* () {
45
+ yield this.delete(event.id);
46
+ })));
47
+ });
48
+ }
49
+ updateStatus(log, statusCode) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ const updatedLog = Object.assign(Object.assign({}, log), { status_code: statusCode, delivered: statusCode === 200 });
52
+ yield this.store('logs').put(log.id, updatedLog);
53
+ return updatedLog;
54
+ });
55
+ }
56
+ }
57
+ exports.WebhookEventsLogger = WebhookEventsLogger;
@@ -0,0 +1,7 @@
1
+ import type { DirectorySyncEventType, Directory, User, Group, EventCallback, DirectorySyncEvent, DirectoryConfig, IWebhookEventsLogger } from '../typings';
2
+ export declare const sendEvent: (event: DirectorySyncEventType, payload: {
3
+ directory: Directory;
4
+ group?: Group | null;
5
+ user?: User | null;
6
+ }, callback?: EventCallback) => Promise<void>;
7
+ export declare const handleEventCallback: (directories: DirectoryConfig, webhookEventsLogger: IWebhookEventsLogger) => Promise<(event: DirectorySyncEvent) => Promise<void>>;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.handleEventCallback = exports.sendEvent = void 0;
16
+ const utils_1 = require("./utils");
17
+ const axios_1 = __importDefault(require("axios"));
18
+ const sendEvent = (event, payload, callback) => __awaiter(void 0, void 0, void 0, function* () {
19
+ const eventTransformed = (0, utils_1.transformEventPayload)(event, payload);
20
+ return callback ? yield callback(eventTransformed) : Promise.resolve();
21
+ });
22
+ exports.sendEvent = sendEvent;
23
+ const handleEventCallback = (directories, webhookEventsLogger) => __awaiter(void 0, void 0, void 0, function* () {
24
+ return (event) => __awaiter(void 0, void 0, void 0, function* () {
25
+ const { tenant, product, directory_id: directoryId } = event;
26
+ const { data: directory } = yield directories.get(directoryId);
27
+ if (!directory) {
28
+ return;
29
+ }
30
+ const { webhook } = directory;
31
+ // If there is no webhook, then we don't need to send an event
32
+ if (webhook.endpoint === '') {
33
+ return;
34
+ }
35
+ webhookEventsLogger.setTenantAndProduct(tenant, product);
36
+ const headers = yield (0, utils_1.createHeader)(webhook.secret, event);
37
+ // Log the events only if `log_webhook_events` is enabled
38
+ const log = directory.log_webhook_events ? yield webhookEventsLogger.log(directory, event) : undefined;
39
+ let status = 200;
40
+ try {
41
+ yield axios_1.default.post(webhook.endpoint, event, {
42
+ headers,
43
+ });
44
+ }
45
+ catch (err) {
46
+ status = err.response ? err.response.status : 500;
47
+ }
48
+ if (log) {
49
+ yield webhookEventsLogger.updateStatus(log, status);
50
+ }
51
+ });
52
+ });
53
+ exports.handleEventCallback = handleEventCallback;
@@ -0,0 +1,6 @@
1
+ import type { DatabaseStore, DirectorySync, JacksonOption } from '../typings';
2
+ declare const directorySync: ({ db, opts, }: {
3
+ db: DatabaseStore;
4
+ opts: JacksonOption;
5
+ }) => Promise<DirectorySync>;
6
+ export default directorySync;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const DirectoryConfig_1 = require("./DirectoryConfig");
13
+ const DirectoryUsers_1 = require("./DirectoryUsers");
14
+ const DirectoryGroups_1 = require("./DirectoryGroups");
15
+ const Users_1 = require("./Users");
16
+ const Groups_1 = require("./Groups");
17
+ const utils_1 = require("./utils");
18
+ const request_1 = require("./request");
19
+ const events_1 = require("./events");
20
+ const WebhookEventsLogger_1 = require("./WebhookEventsLogger");
21
+ const directorySync = ({ db, opts, }) => __awaiter(void 0, void 0, void 0, function* () {
22
+ const directories = new DirectoryConfig_1.DirectoryConfig({ db, opts });
23
+ const users = new Users_1.Users({ db });
24
+ const groups = new Groups_1.Groups({ db });
25
+ const directoryUsers = new DirectoryUsers_1.DirectoryUsers({ directories, users });
26
+ const directoryGroups = new DirectoryGroups_1.DirectoryGroups({ directories, users, groups });
27
+ const webhookEventsLogger = new WebhookEventsLogger_1.WebhookEventsLogger({ db });
28
+ return {
29
+ users,
30
+ groups,
31
+ directories,
32
+ webhookLogs: webhookEventsLogger,
33
+ requests: new request_1.DirectorySyncRequestHandler(directoryUsers, directoryGroups),
34
+ events: {
35
+ callback: yield (0, events_1.handleEventCallback)(directories, webhookEventsLogger),
36
+ },
37
+ providers: () => {
38
+ return (0, utils_1.getDirectorySyncProviders)();
39
+ },
40
+ };
41
+ });
42
+ exports.default = directorySync;
@@ -0,0 +1,7 @@
1
+ import type { DirectorySyncResponse, IDirectoryGroups, IDirectoryUsers, EventCallback, DirectorySyncRequest } from '../typings';
2
+ export declare class DirectorySyncRequestHandler {
3
+ private directoryUsers;
4
+ private directoryGroups;
5
+ constructor(directoryUsers: IDirectoryUsers, directoryGroups: IDirectoryGroups);
6
+ handle(request: DirectorySyncRequest, callback?: EventCallback): Promise<DirectorySyncResponse>;
7
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DirectorySyncRequestHandler = void 0;
13
+ class DirectorySyncRequestHandler {
14
+ constructor(directoryUsers, directoryGroups) {
15
+ this.directoryUsers = directoryUsers;
16
+ this.directoryGroups = directoryGroups;
17
+ }
18
+ handle(request, callback) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ if (request.resourceType === 'users') {
21
+ return yield this.directoryUsers.handleRequest(request, callback);
22
+ }
23
+ else if (request.resourceType === 'groups') {
24
+ return yield this.directoryGroups.handleRequest(request, callback);
25
+ }
26
+ return { status: 404, data: {} };
27
+ });
28
+ }
29
+ }
30
+ exports.DirectorySyncRequestHandler = DirectorySyncRequestHandler;
@@ -0,0 +1,7 @@
1
+ import { Group, User } from '../typings';
2
+ declare const transformUser: (user: User) => User;
3
+ declare const transformGroup: (group: Group) => Group;
4
+ declare const transformUserGroup: (user: User, group: Group) => User & {
5
+ group: Group;
6
+ };
7
+ export { transformUser, transformGroup, transformUserGroup };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformUserGroup = exports.transformGroup = exports.transformUser = void 0;
4
+ const transformUser = (user) => {
5
+ return {
6
+ id: user.id,
7
+ first_name: user.first_name,
8
+ last_name: user.last_name,
9
+ email: user.email,
10
+ active: user.active,
11
+ raw: user.raw,
12
+ };
13
+ };
14
+ exports.transformUser = transformUser;
15
+ const transformGroup = (group) => {
16
+ return {
17
+ id: group.id,
18
+ name: group.name,
19
+ raw: group.raw,
20
+ };
21
+ };
22
+ exports.transformGroup = transformGroup;
23
+ const transformUserGroup = (user, group) => {
24
+ return Object.assign(Object.assign({}, transformUser(user)), { group: transformGroup(group) });
25
+ };
26
+ exports.transformUserGroup = transformUserGroup;
@@ -0,0 +1,39 @@
1
+ import type { Directory, DirectorySyncEvent, DirectorySyncEventType, DirectorySyncGroupMember, Group, User } from '../typings';
2
+ declare const parseGroupOperations: (operations: {
3
+ op: 'add' | 'remove' | 'replace';
4
+ path: string;
5
+ value: any;
6
+ }[]) => {
7
+ action: 'addGroupMember' | 'removeGroupMember';
8
+ members: DirectorySyncGroupMember[];
9
+ } | {
10
+ action: 'updateGroupName';
11
+ displayName: string;
12
+ } | {
13
+ action: 'unknown';
14
+ };
15
+ declare const toGroupMembers: (users: {
16
+ user_id: string;
17
+ }[]) => DirectorySyncGroupMember[];
18
+ export declare const parseUserOperations: (operations: {
19
+ op: 'replace';
20
+ value: any;
21
+ }) => {
22
+ action: 'updateUser' | 'unknown';
23
+ raw: any;
24
+ attributes: Partial<User>;
25
+ };
26
+ declare const getDirectorySyncProviders: () => {
27
+ [K: string]: string;
28
+ };
29
+ declare const transformEventPayload: (event: DirectorySyncEventType, payload: {
30
+ directory: Directory;
31
+ group?: Group | null;
32
+ user?: User | null;
33
+ }) => DirectorySyncEvent;
34
+ declare const createHeader: (secret: string, event: DirectorySyncEvent) => Promise<{
35
+ 'Content-Type': string;
36
+ 'BoxyHQ-Signature': string;
37
+ }>;
38
+ declare const createSignatureString: (secret: string, event: DirectorySyncEvent) => Promise<string>;
39
+ export { parseGroupOperations, toGroupMembers, getDirectorySyncProviders, transformEventPayload, createHeader, createSignatureString, };
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createSignatureString = exports.createHeader = exports.transformEventPayload = exports.getDirectorySyncProviders = exports.toGroupMembers = exports.parseGroupOperations = exports.parseUserOperations = void 0;
16
+ const typings_1 = require("../typings");
17
+ const transform_1 = require("./transform");
18
+ const crypto_1 = __importDefault(require("crypto"));
19
+ const parseGroupOperations = (operations) => {
20
+ const { op, path, value } = operations[0];
21
+ // Add group members
22
+ if (op === 'add' && path === 'members') {
23
+ return {
24
+ action: 'addGroupMember',
25
+ members: value,
26
+ };
27
+ }
28
+ // Remove group members
29
+ if (op === 'remove' && path === 'members') {
30
+ return {
31
+ action: 'removeGroupMember',
32
+ members: value,
33
+ };
34
+ }
35
+ // Remove group members
36
+ if (op === 'remove' && path.startsWith('members[value eq')) {
37
+ return {
38
+ action: 'removeGroupMember',
39
+ members: [{ value: path.split('"')[1] }],
40
+ };
41
+ }
42
+ // Update group name
43
+ if (op === 'replace') {
44
+ return {
45
+ action: 'updateGroupName',
46
+ displayName: value.displayName,
47
+ };
48
+ }
49
+ return {
50
+ action: 'unknown',
51
+ };
52
+ };
53
+ exports.parseGroupOperations = parseGroupOperations;
54
+ const toGroupMembers = (users) => {
55
+ return users.map((user) => ({
56
+ value: user.user_id,
57
+ }));
58
+ };
59
+ exports.toGroupMembers = toGroupMembers;
60
+ const parseUserOperations = (operations) => {
61
+ const { op, value } = operations[0];
62
+ const attributes = {};
63
+ // Update the user
64
+ if (op === 'replace') {
65
+ if ('active' in value) {
66
+ attributes['active'] = value.active;
67
+ }
68
+ if ('name.givenName' in value) {
69
+ attributes['first_name'] = value['name.givenName'];
70
+ }
71
+ if ('name.familyName' in value) {
72
+ attributes['last_name'] = value['name.familyName'];
73
+ }
74
+ return {
75
+ action: 'updateUser',
76
+ raw: value,
77
+ attributes,
78
+ };
79
+ }
80
+ return {
81
+ action: 'unknown',
82
+ raw: value,
83
+ attributes,
84
+ };
85
+ };
86
+ exports.parseUserOperations = parseUserOperations;
87
+ // List of directory sync providers
88
+ // TODO: Fix the return type
89
+ const getDirectorySyncProviders = () => {
90
+ return Object.entries(typings_1.DirectorySyncProviders).reduce((acc, [key, value]) => {
91
+ acc[key] = value;
92
+ return acc;
93
+ }, {});
94
+ };
95
+ exports.getDirectorySyncProviders = getDirectorySyncProviders;
96
+ const transformEventPayload = (event, payload) => {
97
+ const { directory, group, user } = payload;
98
+ const { tenant, product, id: directory_id } = directory;
99
+ const eventPayload = {
100
+ event,
101
+ tenant,
102
+ product,
103
+ directory_id,
104
+ };
105
+ // User events
106
+ if (['user.created', 'user.updated', 'user.deleted'].includes(event) && user) {
107
+ eventPayload['data'] = (0, transform_1.transformUser)(user);
108
+ }
109
+ // Group events
110
+ if (['group.created', 'group.updated', 'group.deleted'].includes(event) && group) {
111
+ eventPayload['data'] = (0, transform_1.transformGroup)(group);
112
+ }
113
+ // Group membership events
114
+ if (['group.user_added', 'group.user_removed'].includes(event) && user && group) {
115
+ eventPayload['data'] = (0, transform_1.transformUserGroup)(user, group);
116
+ }
117
+ return eventPayload;
118
+ };
119
+ exports.transformEventPayload = transformEventPayload;
120
+ // Create request headers
121
+ const createHeader = (secret, event) => __awaiter(void 0, void 0, void 0, function* () {
122
+ return {
123
+ 'Content-Type': 'application/json',
124
+ 'BoxyHQ-Signature': yield createSignatureString(secret, event),
125
+ };
126
+ });
127
+ exports.createHeader = createHeader;
128
+ // Create a signature string
129
+ const createSignatureString = (secret, event) => __awaiter(void 0, void 0, void 0, function* () {
130
+ if (!secret) {
131
+ return '';
132
+ }
133
+ const timestamp = new Date().getTime();
134
+ const signature = crypto_1.default
135
+ .createHmac('sha256', secret)
136
+ .update(`${timestamp}.${JSON.stringify(event)}`)
137
+ .digest('hex');
138
+ return `t=${timestamp},s=${signature}`;
139
+ });
140
+ exports.createSignatureString = createSignatureString;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { DirectorySync, JacksonOption } from './typings';
1
2
  import { AdminController } from './controller/admin';
2
3
  import { APIController } from './controller/api';
3
4
  import { OAuthController } from './controller/oauth';
@@ -5,13 +6,13 @@ import { HealthCheckController } from './controller/health-check';
5
6
  import { LogoutController } from './controller/logout';
6
7
  import { OidcDiscoveryController } from './controller/oidc-discovery';
7
8
  import { SPSAMLConfig } from './controller/sp-config';
8
- import { JacksonOption } from './typings';
9
9
  export declare const controllers: (opts: JacksonOption) => Promise<{
10
10
  apiController: APIController;
11
11
  oauthController: OAuthController;
12
12
  adminController: AdminController;
13
13
  logoutController: LogoutController;
14
14
  healthCheckController: HealthCheckController;
15
+ directorySync: DirectorySync;
15
16
  oidcDiscoveryController: OidcDiscoveryController;
16
17
  spConfig: SPSAMLConfig;
17
18
  }>;