Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest, userIdDropdown } from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
|
||||
export const activateUserAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'activate_user',
|
||||
displayName: 'Activate User',
|
||||
description: 'Activate a previously deactivated or pending user',
|
||||
props: {
|
||||
userId: userIdDropdown(),
|
||||
sendEmail: Property.Checkbox({
|
||||
displayName: 'Send Email',
|
||||
description: 'Send activation email to user',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const userId = context.propsValue.userId;
|
||||
const sendEmail = context.propsValue.sendEmail ? 'true' : 'false';
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/users/${userId}/lifecycle/activate?sendEmail=${sendEmail}`,
|
||||
HttpMethod.POST
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest, userIdDropdown, groupIdDropdown } from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
|
||||
|
||||
export const addUserToGroupAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'add_user_to_group',
|
||||
displayName: 'Add User to Group',
|
||||
description: 'Add a user to a specific Okta group',
|
||||
props: {
|
||||
userId: userIdDropdown(),
|
||||
groupId: groupIdDropdown,
|
||||
},
|
||||
async run(context) {
|
||||
const userId = context.propsValue.userId;
|
||||
const groupId = context.propsValue.groupId;
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/groups/${groupId}/users/${userId}`,
|
||||
HttpMethod.PUT
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
userId,
|
||||
groupId,
|
||||
message: 'User added to group',
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,65 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest } from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
|
||||
export const createUserAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'create_user',
|
||||
displayName: 'Create User',
|
||||
description: 'Creates a user without credentials and sends account creation prompt via email',
|
||||
props: {
|
||||
firstName: Property.ShortText({
|
||||
displayName: 'First Name',
|
||||
description: 'User first name',
|
||||
required: true,
|
||||
}),
|
||||
lastName: Property.ShortText({
|
||||
displayName: 'Last Name',
|
||||
description: 'User last name',
|
||||
required: true,
|
||||
}),
|
||||
email: Property.ShortText({
|
||||
displayName: 'Email',
|
||||
description: 'User email address',
|
||||
required: true,
|
||||
}),
|
||||
login: Property.ShortText({
|
||||
displayName: 'Login',
|
||||
description: 'User login (typically same as email)',
|
||||
required: false,
|
||||
}),
|
||||
mobilePhone: Property.ShortText({
|
||||
displayName: 'Mobile Phone',
|
||||
description: 'User mobile phone number',
|
||||
required: false,
|
||||
}),
|
||||
sendEmail: Property.Checkbox({
|
||||
displayName: 'Send Email',
|
||||
description: 'Send account creation email to user',
|
||||
required: false,
|
||||
defaultValue: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const userData = {
|
||||
profile: {
|
||||
firstName: context.propsValue.firstName,
|
||||
lastName: context.propsValue.lastName,
|
||||
email: context.propsValue.email,
|
||||
login: context.propsValue.login || context.propsValue.email,
|
||||
},
|
||||
};
|
||||
|
||||
const queryParam = context.propsValue.sendEmail ? '?activate=true' : '';
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/users${queryParam}`,
|
||||
HttpMethod.POST,
|
||||
userData
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest, userIdDropdown } from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
|
||||
export const deactivateUserAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'deactivate_user',
|
||||
displayName: 'Deactivate User',
|
||||
description: 'Deactivate (disable) a user in Okta',
|
||||
props: {
|
||||
userId: userIdDropdown(),
|
||||
sendEmail: Property.Checkbox({
|
||||
displayName: 'Send Email',
|
||||
description: 'Send deactivation email to user',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const userId = context.propsValue.userId;
|
||||
const sendEmail = context.propsValue.sendEmail ? 'true' : 'false';
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/users/${userId}/lifecycle/deactivate?sendEmail=${sendEmail}`,
|
||||
HttpMethod.POST
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest } from '../common/common';
|
||||
|
||||
|
||||
|
||||
export const findGroupByNameAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'find_group_by_name',
|
||||
displayName: 'Find Group by Name',
|
||||
description: 'Search for an Okta group by name',
|
||||
props: {
|
||||
groupName: Property.ShortText({
|
||||
displayName: 'Group Name',
|
||||
description: 'The group name to search for',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const groupName = context.propsValue.groupName;
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/groups?q=${encodeURIComponent(groupName)}`
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest } from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
|
||||
export const findUserByEmailAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'find_user_by_email',
|
||||
displayName: 'Find User by Email',
|
||||
description: 'Look up an Okta user by their email address',
|
||||
props: {
|
||||
domain: Property.ShortText({
|
||||
displayName: 'Okta Domain',
|
||||
description: 'Your Okta organization domain',
|
||||
required: true,
|
||||
}),
|
||||
email: Property.ShortText({
|
||||
displayName: 'Email',
|
||||
description: 'The user email address',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const email = context.propsValue.email;
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/users?search=profile.email eq "${email}"`,
|
||||
HttpMethod.GET,
|
||||
context.propsValue.domain
|
||||
);
|
||||
|
||||
if (response.body && response.body.length > 0) {
|
||||
return response.body[0];
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: `No user found with email: ${email}`,
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
oktaAuth,
|
||||
makeOktaRequest,
|
||||
userIdDropdown,
|
||||
groupIdDropdown,
|
||||
} from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const removeUserFromGroupAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'remove_user_from_group',
|
||||
displayName: 'Remove User from Group',
|
||||
description: 'Remove a user from an Okta group',
|
||||
props: {
|
||||
groupId: groupIdDropdown,
|
||||
userId: userIdDropdown(true),
|
||||
},
|
||||
async run(context) {
|
||||
const userId = context.propsValue.userId;
|
||||
const groupId = context.propsValue.groupId;
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/groups/${groupId}/users/${userId}`,
|
||||
HttpMethod.DELETE
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
userId,
|
||||
groupId,
|
||||
message: 'User removed from group',
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest, userIdDropdown } from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
|
||||
export const suspendUserAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'suspend_user',
|
||||
displayName: 'Suspend User',
|
||||
description: 'Temporarily suspend a user in Okta',
|
||||
props: {
|
||||
userId: userIdDropdown(),
|
||||
},
|
||||
async run(context) {
|
||||
const userId = context.propsValue.userId;
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/users/${userId}/lifecycle/suspend`,
|
||||
HttpMethod.POST
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest, userIdDropdown } from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
|
||||
|
||||
export const updateUserAction = createAction({
|
||||
auth: oktaAuth,
|
||||
name: 'update_user',
|
||||
displayName: 'Update User',
|
||||
description: 'Update user profile information',
|
||||
props: {
|
||||
userId: userIdDropdown(),
|
||||
firstName: Property.ShortText({
|
||||
displayName: 'First Name',
|
||||
description: 'Updated first name',
|
||||
required: false,
|
||||
}),
|
||||
lastName: Property.ShortText({
|
||||
displayName: 'Last Name',
|
||||
description: 'Updated last name',
|
||||
required: false,
|
||||
}),
|
||||
email: Property.ShortText({
|
||||
displayName: 'Email',
|
||||
description: 'Updated email address',
|
||||
required: false,
|
||||
}),
|
||||
mobilePhone: Property.ShortText({
|
||||
displayName: 'Mobile Phone',
|
||||
description: 'Updated mobile phone number',
|
||||
required: false,
|
||||
}),
|
||||
customAttributes: Property.Json({
|
||||
displayName: 'Custom Attributes',
|
||||
description: 'JSON object with custom profile attributes',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const userId = context.propsValue.userId;
|
||||
const userData: any = {
|
||||
profile: {},
|
||||
};
|
||||
|
||||
if (context.propsValue.firstName) {
|
||||
userData.profile.firstName = context.propsValue.firstName;
|
||||
}
|
||||
if (context.propsValue.lastName) {
|
||||
userData.profile.lastName = context.propsValue.lastName;
|
||||
}
|
||||
if (context.propsValue.email) {
|
||||
userData.profile.email = context.propsValue.email;
|
||||
}
|
||||
if (context.propsValue.mobilePhone) {
|
||||
userData.profile.mobilePhone = context.propsValue.mobilePhone;
|
||||
}
|
||||
if (context.propsValue.customAttributes) {
|
||||
userData.profile = { ...userData.profile, ...context.propsValue.customAttributes };
|
||||
}
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/users/${userId}`,
|
||||
HttpMethod.POST,
|
||||
userData
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,162 @@
|
||||
import { PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
|
||||
|
||||
export const oktaAuth = PieceAuth.CustomAuth({
|
||||
required: true,
|
||||
props: {
|
||||
domain: Property.ShortText({
|
||||
displayName: 'Okta Domain',
|
||||
description: 'Your Okta organization domain (e.g., https://dev-12345.okta.com or dev-12345.okta.com)',
|
||||
required: true,
|
||||
}),
|
||||
apiToken: Property.ShortText({
|
||||
displayName: 'API Token',
|
||||
description: 'Your Okta API token (from Admin → Security → API → Tokens)',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
export async function makeOktaRequest(
|
||||
auth: any,
|
||||
endpoint: string,
|
||||
method: HttpMethod = HttpMethod.GET,
|
||||
body?: any
|
||||
) {
|
||||
const apiToken = auth.apiToken;
|
||||
let domain = auth.domain;
|
||||
|
||||
if (!domain) {
|
||||
throw new Error('Okta domain is required');
|
||||
}
|
||||
|
||||
if (!domain.startsWith('https://') && !domain.startsWith('http://')) {
|
||||
domain = `https://${domain}`;
|
||||
}
|
||||
domain = domain.replace(/\/$/, '');
|
||||
|
||||
return await httpClient.sendRequest({
|
||||
method,
|
||||
url: `${domain}/api/v1${endpoint}`,
|
||||
headers: {
|
||||
'Authorization': `SSWS ${apiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
body,
|
||||
});
|
||||
}
|
||||
|
||||
export const userIdDropdown = (groupusers = false) =>
|
||||
Property.Dropdown({
|
||||
auth: oktaAuth,
|
||||
displayName: 'User',
|
||||
description: 'Select a user',
|
||||
required: true,
|
||||
refreshers: ['auth', 'groupId'],
|
||||
options: async ({ auth, groupId }) => {
|
||||
try {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'select auth first',
|
||||
};
|
||||
}
|
||||
if (groupusers && !groupId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'please select groupId first',
|
||||
};
|
||||
}
|
||||
const path = groupusers
|
||||
? `/groups/${groupId}/users`
|
||||
: '/users';
|
||||
const response = await makeOktaRequest(
|
||||
auth,
|
||||
path,
|
||||
HttpMethod.GET,
|
||||
undefined
|
||||
);
|
||||
|
||||
const users = await response.body;
|
||||
console.log(JSON.stringify(users, null, 2));
|
||||
if (!Array.isArray(users)) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'No users found',
|
||||
};
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options: users.map((user: any) => ({
|
||||
label:
|
||||
user.profile.firstName +
|
||||
' ' +
|
||||
user.profile.lastName +
|
||||
' (' +
|
||||
user.profile.email +
|
||||
')',
|
||||
value: user.id,
|
||||
})),
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Error fetching users',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const groupIdDropdown =
|
||||
Property.Dropdown({
|
||||
auth: oktaAuth,
|
||||
displayName: 'Group',
|
||||
description: 'Select a group',
|
||||
required: true,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
try {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'No groups found',
|
||||
};
|
||||
}
|
||||
const response = await makeOktaRequest(
|
||||
auth,
|
||||
'/groups',
|
||||
HttpMethod.GET
|
||||
);
|
||||
|
||||
const groups = await response.body;
|
||||
if (!Array.isArray(groups)) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'No groups found',
|
||||
};
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options: groups.map((group: any) => ({
|
||||
label: group.profile.name,
|
||||
value: group.id,
|
||||
})),
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Error fetching groups',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,268 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
Property,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { oktaAuth, makeOktaRequest } from '../common/common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { WebhookHandshakeStrategy } from '@activepieces/shared';
|
||||
|
||||
export const newEventTrigger = createTrigger({
|
||||
auth: oktaAuth,
|
||||
name: 'new_event',
|
||||
displayName: 'New Event',
|
||||
description: 'Fires when a new Okta event is generated',
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
props: {
|
||||
eventTypes: Property.StaticMultiSelectDropdown({
|
||||
displayName: 'Event Types to Monitor',
|
||||
description: 'Select which event types to trigger on',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'User Created', value: 'user.lifecycle.create' },
|
||||
{ label: 'User Activated', value: 'user.lifecycle.activate' },
|
||||
{ label: 'User Deactivated', value: 'user.lifecycle.deactivate' },
|
||||
{ label: 'User Suspended', value: 'user.lifecycle.suspend' },
|
||||
{ label: 'User Unsuspended', value: 'user.lifecycle.unsuspend' },
|
||||
{ label: 'User Deleted', value: 'user.lifecycle.delete.completed' },
|
||||
{ label: 'User Added to Group', value: 'group.user_membership.add' },
|
||||
{
|
||||
label: 'User Removed from Group',
|
||||
value: 'group.user_membership.remove',
|
||||
},
|
||||
{ label: 'Group Created', value: 'group.lifecycle.create' },
|
||||
{ label: 'Group Deleted', value: 'group.lifecycle.delete' },
|
||||
{ label: 'User Login', value: 'user.session.start' },
|
||||
{ label: 'User Logout', value: 'user.session.end' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
hookName: Property.ShortText({
|
||||
displayName: 'Hook Name',
|
||||
description: 'Name for the Okta Event Hook (optional)',
|
||||
required: false,
|
||||
defaultValue: 'Activepieces Webhook',
|
||||
}),
|
||||
},
|
||||
handshakeConfiguration: {
|
||||
strategy: WebhookHandshakeStrategy.HEADER_PRESENT,
|
||||
paramName: 'x-okta-verification-challenge',
|
||||
},
|
||||
async onHandshake(context) {
|
||||
const challengeValue =
|
||||
context.payload.headers['x-okta-verification-challenge'];
|
||||
|
||||
if (challengeValue) {
|
||||
console.log('Okta verification challenge received:', challengeValue);
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
verification: challengeValue,
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: 400,
|
||||
body: { error: 'No verification challenge found' },
|
||||
};
|
||||
},
|
||||
async onEnable(context) {
|
||||
try {
|
||||
const eventTypes = context.propsValue.eventTypes || [];
|
||||
const hookName = context.propsValue.hookName || 'Webhook';
|
||||
|
||||
const existingHooks = await makeOktaRequest(
|
||||
context.auth,
|
||||
'/eventHooks',
|
||||
HttpMethod.GET
|
||||
);
|
||||
|
||||
const existingHook = existingHooks.body?.find(
|
||||
(hook: any) =>
|
||||
hook.name === hookName &&
|
||||
hook.channel?.config?.uri === context.webhookUrl
|
||||
);
|
||||
|
||||
let hookId: string;
|
||||
|
||||
if (existingHook) {
|
||||
hookId = existingHook.id;
|
||||
} else {
|
||||
const eventHookPayload = {
|
||||
name: hookName,
|
||||
events: {
|
||||
type: 'EVENT_TYPE',
|
||||
items:
|
||||
eventTypes.length > 0
|
||||
? eventTypes
|
||||
: [
|
||||
'user.lifecycle.create',
|
||||
'user.lifecycle.activate',
|
||||
'user.lifecycle.deactivate',
|
||||
'user.lifecycle.suspend',
|
||||
'user.lifecycle.unsuspend',
|
||||
'user.lifecycle.update',
|
||||
'user.lifecycle.delete',
|
||||
'group.user_membership.add',
|
||||
'group.user_membership.remove',
|
||||
'group.lifecycle.create',
|
||||
'group.lifecycle.update',
|
||||
'group.lifecycle.delete',
|
||||
'user.session.start',
|
||||
'user.session.end',
|
||||
'user.authentication.auth_failed',
|
||||
],
|
||||
},
|
||||
channel: {
|
||||
type: 'HTTP',
|
||||
version: '1.0.0',
|
||||
config: {
|
||||
uri: context.webhookUrl,
|
||||
method: 'POST',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
'/eventHooks',
|
||||
HttpMethod.POST,
|
||||
eventHookPayload
|
||||
);
|
||||
|
||||
if (!response.body?.id) {
|
||||
throw new Error(
|
||||
'Failed to create event hook: ' + JSON.stringify(response.body)
|
||||
);
|
||||
}
|
||||
|
||||
hookId = response.body.id;
|
||||
console.log(`Created new event hook: ${hookId}`);
|
||||
}
|
||||
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
`/eventHooks/${hookId}/lifecycle/verify`,
|
||||
HttpMethod.POST
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error(
|
||||
'Failed to verify event hook: ' + JSON.stringify(response.body)
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating Okta event hook:', error);
|
||||
throw new Error(`Failed to setup Okta event hook: ${error}`);
|
||||
}
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
try {
|
||||
const hookId = await context.store.get('hookId');
|
||||
|
||||
if (hookId) {
|
||||
try {
|
||||
await makeOktaRequest(
|
||||
context.auth,
|
||||
`/eventHooks/${hookId}/lifecycle/deactivate`,
|
||||
HttpMethod.POST
|
||||
);
|
||||
console.log(`Deactivated event hook: ${hookId}`);
|
||||
} catch (deactivateError) {
|
||||
console.warn('Failed to deactivate event hook:', deactivateError);
|
||||
}
|
||||
|
||||
try {
|
||||
await makeOktaRequest(
|
||||
context.auth,
|
||||
`/eventHooks/${hookId}`,
|
||||
HttpMethod.DELETE
|
||||
);
|
||||
console.log(`Deleted event hook: ${hookId}`);
|
||||
} catch (deleteError) {
|
||||
console.warn('Failed to delete event hook:', deleteError);
|
||||
}
|
||||
}
|
||||
await context.store.delete('hookId');
|
||||
} catch (error) {
|
||||
console.error('Error cleaning up Okta event hook:', error);
|
||||
}
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
const payload: any = context.payload.body;
|
||||
console.log("firstfdsdfsdf",JSON.stringify(payload))
|
||||
const configuredEventTypes = context.propsValue.eventTypes || [];
|
||||
|
||||
if (!payload.data?.events || !Array.isArray(payload.data.events)) {
|
||||
console.log('No events found in payload, skipping');
|
||||
return [];
|
||||
}
|
||||
|
||||
const filteredEvents = [];
|
||||
|
||||
for (const event of payload.data.events) {
|
||||
|
||||
if (configuredEventTypes.length > 0) {
|
||||
if (!configuredEventTypes.includes(event.eventType)) {
|
||||
console.log(
|
||||
`Event type ${event.eventType} not in configured types, skipping`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
filteredEvents.push(event);
|
||||
}
|
||||
|
||||
return filteredEvents;
|
||||
},
|
||||
|
||||
async test(context) {
|
||||
try {
|
||||
const response = await makeOktaRequest(
|
||||
context.auth,
|
||||
'/logs?limit=1',
|
||||
HttpMethod.GET
|
||||
);
|
||||
return response.body || [];
|
||||
} catch (error) {
|
||||
console.error('Test error:', error);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
sampleData: {
|
||||
eventId: 'evt_123456789',
|
||||
timestamp: new Date().toISOString(),
|
||||
version: '0',
|
||||
severity: 'INFO',
|
||||
eventType: 'user.lifecycle.create',
|
||||
displayMessage: 'User created: user@example.com',
|
||||
actor: {
|
||||
id: 'admin123',
|
||||
type: 'User',
|
||||
alternateId: 'admin@example.com',
|
||||
displayName: 'Admin User',
|
||||
},
|
||||
outcome: {
|
||||
result: 'SUCCESS',
|
||||
reason: '',
|
||||
},
|
||||
target: [
|
||||
{
|
||||
id: 'user123',
|
||||
type: 'User',
|
||||
alternateId: 'user@example.com',
|
||||
displayName: 'New User',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user