n8n/packages/nodes-base/nodes/Okta/UserFunctions.ts
Shireen Missi 5cac0f339d
feat(Okta Node): Add Okta Node (#10278)
Co-authored-by: Giulio Andreini <g.andreini@gmail.com>
Co-authored-by: Elias Meire <elias@meire.dev>
2024-08-12 16:49:06 +01:00

171 lines
4.5 KiB
TypeScript

import type {
DeclarativeRestApiSettings,
IDataObject,
IExecuteFunctions,
IExecutePaginationFunctions,
IExecuteSingleFunctions,
IHookFunctions,
IHttpRequestMethods,
IHttpRequestOptions,
ILoadOptionsFunctions,
IN8nHttpFullResponse,
INodeExecutionData,
INodeListSearchResult,
INodePropertyOptions,
} from 'n8n-workflow';
type OktaUser = {
status: string;
created: string;
activated: string;
lastLogin: string;
lastUpdated: string;
passwordChanged: string;
profile: {
login: string;
email: string;
firstName: string;
lastName: string;
};
id: string;
};
export async function oktaApiRequest(
this: IExecuteFunctions | IExecuteSingleFunctions | IHookFunctions | ILoadOptionsFunctions,
method: IHttpRequestMethods,
resource: string,
body: IDataObject = {},
qs: IDataObject = {},
url?: string,
option: IDataObject = {},
): Promise<OktaUser[]> {
const credentials = await this.getCredentials('oktaApi');
const baseUrl = `${credentials.url as string}/api/v1/${resource}`;
const options: IHttpRequestOptions = {
headers: {
'Content-Type': 'application/json',
},
method,
body: Object.keys(body).length ? body : undefined,
qs: Object.keys(qs).length ? qs : undefined,
url: url ?? baseUrl,
json: true,
...option,
};
return await (this.helpers.httpRequestWithAuthentication.call(
this,
'oktaApi',
options,
) as Promise<OktaUser[]>);
}
export async function getUsers(
this: ILoadOptionsFunctions,
filter?: string,
): Promise<INodeListSearchResult> {
const responseData: OktaUser[] = await oktaApiRequest.call(this, 'GET', '/users/');
const filteredUsers = responseData.filter((user) => {
if (!filter) return true;
const username = `${user.profile.login}`.toLowerCase();
return username.includes(filter.toLowerCase());
});
const users: INodePropertyOptions[] = filteredUsers.map((user) => ({
name: `${user.profile.login}`,
value: user.id,
}));
return {
results: users,
};
}
function simplifyOktaUser(item: OktaUser): IDataObject {
return {
id: item.id,
status: item.status,
created: item.created,
activated: item.activated,
lastLogin: item.lastLogin,
lastUpdated: item.lastUpdated,
passwordChanged: item.passwordChanged,
profile: {
firstName: item.profile.firstName,
lastName: item.profile.lastName,
login: item.profile.login,
email: item.profile.email,
},
};
}
export async function simplifyGetAllResponse(
this: IExecuteSingleFunctions,
items: INodeExecutionData[],
_response: IN8nHttpFullResponse,
): Promise<INodeExecutionData[]> {
if (items.length === 0) return items;
const simplify = this.getNodeParameter('simplify');
if (!simplify)
return ((items[0].json as unknown as IDataObject[]) ?? []).map((item: IDataObject) => ({
json: item,
headers: _response.headers,
})) as INodeExecutionData[];
let simplifiedItems: INodeExecutionData[] = [];
if (items[0].json) {
const jsonArray = items[0].json as unknown;
simplifiedItems = (jsonArray as OktaUser[]).map((item: OktaUser) => {
const simplifiedItem = simplifyOktaUser(item);
return {
json: simplifiedItem,
headers: _response.headers,
};
});
}
return simplifiedItems;
}
export async function simplifyGetResponse(
this: IExecuteSingleFunctions,
items: INodeExecutionData[],
_response: IN8nHttpFullResponse,
): Promise<INodeExecutionData[]> {
const simplify = this.getNodeParameter('simplify');
if (!simplify) return items;
const item = items[0].json as OktaUser;
const simplifiedItem = simplifyOktaUser(item);
return [
{
json: simplifiedItem,
},
] as INodeExecutionData[];
}
export const getCursorPaginator = () => {
return async function cursorPagination(
this: IExecutePaginationFunctions,
requestOptions: DeclarativeRestApiSettings.ResultOptions,
): Promise<INodeExecutionData[]> {
if (!requestOptions.options.qs) {
requestOptions.options.qs = {};
}
let items: INodeExecutionData[] = [];
let responseData: INodeExecutionData[];
let nextCursor: string | undefined = undefined;
const returnAll = this.getNodeParameter('returnAll', true) as boolean;
do {
requestOptions.options.qs.limit = 200;
requestOptions.options.qs.after = nextCursor;
responseData = await this.makeRoutingRequest(requestOptions);
if (responseData.length > 0) {
const headers = responseData[responseData.length - 1].headers;
const headersLink = (headers as IDataObject)?.link as string | undefined;
nextCursor = headersLink?.split('after=')[1]?.split('&')[0]?.split('>')[0];
}
items = items.concat(responseData);
} while (returnAll && nextCursor);
return items;
};
};