mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-05-15 13:17:59 +02:00
cf42d6aecb
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
3323 lines
81 KiB
JavaScript
3323 lines
81 KiB
JavaScript
import {
|
|
getJSON,
|
|
postJSON,
|
|
postMultipart,
|
|
patchJSON,
|
|
deleteJSON,
|
|
deleteReq,
|
|
newResponse,
|
|
putJSON
|
|
} from './client.js';
|
|
/**
|
|
* Represents the response object returned by the API functions.
|
|
* @typedef {Object} ApiResponse
|
|
* @property {boolean} success - Indicates whether the request was successful.
|
|
* @property {number} statusCode - The status code of the response.
|
|
* @property {string} error - The error message, if any.
|
|
* @property {any} data - The data returned by the request.
|
|
*/
|
|
|
|
/**
|
|
* @typedef {object} APISenderHeader
|
|
* @property {string} [id]
|
|
* @property {string} key
|
|
* @property {string} value
|
|
* @property {boolean} isRequestHeader
|
|
* @property {string} [apiSenderID]
|
|
*/
|
|
|
|
/**
|
|
* TableURLParams is a type that represents the query parameters for a table.
|
|
*
|
|
* @typedef {object} TableURLParams
|
|
* @property {number} [currentPage]
|
|
* @property {number} [perPage]
|
|
* @property {string} [sortBy]
|
|
* @property {string} [sortOrder]
|
|
* @property {string} [search]
|
|
*/
|
|
|
|
/**
|
|
* Calculates the offset for the specified page and per page count.
|
|
*
|
|
* @param {number} currentPage
|
|
* @param {number} perPage
|
|
* @returns {number}
|
|
*/
|
|
const getOffset = (currentPage, perPage) => {
|
|
return (currentPage - 1) * perPage;
|
|
};
|
|
|
|
const appendQuery = (query) => {
|
|
if (!query) {
|
|
return '_'; // append after this method hack
|
|
}
|
|
|
|
// extract only the state properties we need, avoiding methods and internal properties
|
|
// handle both tableURLParams objects and plain objects safely
|
|
const currentPage = query.currentPage || query.page || 1;
|
|
const perPage = query.perPage || 10;
|
|
const sortBy = query.sortBy || '';
|
|
const sortOrder = query.sortOrder || '';
|
|
const search = query.search || '';
|
|
const includeTest = query.includeTest;
|
|
|
|
const offset = getOffset(currentPage, perPage);
|
|
|
|
let urlQuery = `offset=${offset}&limit=${perPage}`;
|
|
if (sortBy) {
|
|
// normalize the sortby field by lowercasing and replacing spacing with underscores
|
|
const normalizedSortBy = sortBy.toLowerCase().replace(/\s+/g, '_');
|
|
urlQuery += `&sortBy=${normalizedSortBy}`;
|
|
}
|
|
if (sortOrder) {
|
|
urlQuery += `&sortOrder=${sortOrder}`;
|
|
} else {
|
|
urlQuery += `&sortOrder=asc`;
|
|
}
|
|
if (search) {
|
|
urlQuery += `&search=${search}`;
|
|
}
|
|
if (includeTest === true) {
|
|
urlQuery += `&includeTest=true`;
|
|
} else if (includeTest === false) {
|
|
urlQuery += `&includeTest=false`;
|
|
}
|
|
|
|
return urlQuery;
|
|
};
|
|
/**
|
|
* API is for interacting with the backend API.
|
|
* Use API.instance to get a singleton instance of the API class.
|
|
*/
|
|
export class API {
|
|
/**
|
|
* @param {API|null} _instance
|
|
*/
|
|
static #_instance = null;
|
|
|
|
/**
|
|
* instance is the singleton instance of the API class.
|
|
*
|
|
* @returns {API}
|
|
*/
|
|
static get instance() {
|
|
if (!API.#_instance) {
|
|
API.#_instance = new API();
|
|
}
|
|
return API.#_instance;
|
|
}
|
|
|
|
/**
|
|
* The base URL or PATH of the API.
|
|
*
|
|
* @type {string}
|
|
*/
|
|
#_url;
|
|
|
|
/**
|
|
* The version of the API.
|
|
*
|
|
* @type {string}
|
|
*/
|
|
#_version;
|
|
|
|
/**
|
|
* Creates a new API instance.
|
|
*
|
|
* @param {string} url
|
|
*/
|
|
constructor(url = '/api', version = '/v1') {
|
|
this.#_version = version;
|
|
this.#_url = url;
|
|
}
|
|
|
|
/**
|
|
* Constructs the full URL for the specified path.
|
|
*
|
|
* @param {string} path
|
|
* @returns {string}
|
|
*/
|
|
getPath(path) {
|
|
return `${this.#_url}${this.#_version}${path}`;
|
|
}
|
|
|
|
/**
|
|
* builds a query arg for the company ID to
|
|
* be appended to the path or a empty string if the companyID is not provided.
|
|
*/
|
|
appendCompanyQuery(companyID) {
|
|
if (!companyID) {
|
|
return '';
|
|
}
|
|
return `&${this.companyQuery(companyID)}`;
|
|
}
|
|
|
|
companyQuery(companyID) {
|
|
if (!companyID) {
|
|
return '';
|
|
}
|
|
return `companyID=${companyID}`;
|
|
}
|
|
|
|
/**
|
|
* builds a query arg for the type ID to
|
|
* be appended to the path or a empty string if the typeID is not provided.
|
|
*/
|
|
appendTypeQuery(typeID) {
|
|
if (!typeID) {
|
|
return '';
|
|
}
|
|
return `&typeID=${typeID}`;
|
|
}
|
|
|
|
/**
|
|
* application is the API for application related operations.
|
|
*/
|
|
application = {
|
|
/**
|
|
* Feature flags - get the features the application is build with
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
features: async () => {
|
|
return await getJSON(this.getPath('/features'));
|
|
},
|
|
|
|
/**
|
|
* Install the application.
|
|
*
|
|
* @param {string} username
|
|
* @param {string} userFullname
|
|
* @param {string} newPassword
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
install: async (username, userFullname, newPassword) => {
|
|
return await postJSON(this.getPath(`/install`), {
|
|
username,
|
|
userFullname,
|
|
newPassword
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Health check endpoint
|
|
* @returns {Promise<boolean>}
|
|
*/
|
|
health: async () => {
|
|
const res = await fetch(this.getPath('/healthz'), {
|
|
method: 'GET'
|
|
});
|
|
return res.status === 200;
|
|
},
|
|
|
|
/**
|
|
* Check if update is available (cached)
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
isUpdateAvailableCached: async () => {
|
|
return await getJSON(this.getPath(`/update/available/cached`));
|
|
},
|
|
|
|
/**
|
|
* Check if update is available (manual check)
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
isUpdateAvailable: async () => {
|
|
return await getJSON(this.getPath(`/update/available`));
|
|
},
|
|
|
|
/**
|
|
* Get update details
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getUpdateDetails: async () => {
|
|
return await getJSON(this.getPath(`/update`));
|
|
},
|
|
/**
|
|
* Performs an update
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
runUpdate: async () => {
|
|
return await postJSON(this.getPath(`/update`));
|
|
},
|
|
|
|
/**
|
|
* Create a backup
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
createBackup: async () => {
|
|
return await postJSON(this.getPath(`/backup/create`));
|
|
},
|
|
|
|
/**
|
|
* List available backups
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
listBackups: async () => {
|
|
return await getJSON(this.getPath(`/backup/list`));
|
|
},
|
|
|
|
/**
|
|
* Download a backup file
|
|
* @param {string} filename - name of the backup file
|
|
* @returns {Promise<Blob>}
|
|
*/
|
|
downloadBackup: async (filename) => {
|
|
const response = await fetch(
|
|
this.getPath(`/backup/download/${encodeURIComponent(filename)}`),
|
|
{
|
|
method: 'GET',
|
|
credentials: 'same-origin'
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to download backup: ${response.statusText}`);
|
|
}
|
|
|
|
return await response.blob();
|
|
},
|
|
|
|
/**
|
|
* Install example templates from GitHub during setup
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
installTemplates: async () => {
|
|
return await postJSON(this.getPath(`/install/templates`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* asset is the API for asset (static files) related operations.
|
|
*/
|
|
asset = {
|
|
/**
|
|
* Get assets for a domain.
|
|
*
|
|
* @param {string} domain
|
|
* @param {string|null} companyID
|
|
* @param {TableURLParams} options
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByDomain: async (domain, companyID, options) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/asset/domain/${domain}?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get asset by id
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/asset/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get asset by id in base64 with mime type
|
|
*
|
|
* @param {string} domain
|
|
* @param {string} path
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getRaw: async (domain, path) => {
|
|
return await getJSON(this.getPath(`/asset/view/domain/${domain}/${path}`));
|
|
},
|
|
|
|
/**
|
|
* Get all assets for a domain using pagination.
|
|
*
|
|
* @param {*} data form data
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
upload: async (data) => {
|
|
const res = await fetch(this.getPath(`/asset`), {
|
|
method: 'POST',
|
|
// content-type is set automatically by the browser
|
|
body: data
|
|
});
|
|
// TODO all of these to json things can fail we need to do something more
|
|
const body = await res.json();
|
|
|
|
return newResponse(body.success, res.status, body.error, body.data);
|
|
},
|
|
|
|
/**
|
|
* Update an asset
|
|
*
|
|
* @param {string} id
|
|
* @param {string} name
|
|
* @param {string} description
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async (id, name, description) => {
|
|
return await patchJSON(this.getPath(`/asset/${id}`), {
|
|
name: name,
|
|
description: description
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get all assets for a domain using pagination.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/asset/${id}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* atttachment is the API for attachment related operations.
|
|
* @type {Object}
|
|
*/
|
|
attachment = {
|
|
/**
|
|
* Get attachments.
|
|
*
|
|
* @param {string|null} companyID can be null for global context
|
|
* @param {TableURLParams} options
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByContext: async (companyID, options) => {
|
|
return await getJSON(
|
|
this.getPath(`/attachment?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get an attachment by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/attachment/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get the content and mime type of an attachment by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getContentByID: async (id) => {
|
|
return await getJSON(this.getPath(`/attachment/${id}/content`));
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param {object} attachment
|
|
* @param {string} attachment.id
|
|
* @param {string} attachment.name
|
|
* @param {string} attachment.description
|
|
* @param {Boolean} attachment.embeddedContent
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async ({ id, name, description, embeddedContent }) => {
|
|
return await patchJSON(this.getPath(`/attachment/${id}`), {
|
|
name: name,
|
|
description: description,
|
|
embeddedContent: embeddedContent
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Upload a new attachment.
|
|
*
|
|
* @param {FormData} data
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
upload: async (data) => {
|
|
const res = await fetch(this.getPath(`/attachment`), {
|
|
method: 'POST',
|
|
// content-type is set automatically by the browser
|
|
body: data
|
|
});
|
|
// TODO all of these to json things can fail we need to do something more
|
|
const body = await res.json();
|
|
|
|
return newResponse(body.success, res.status, body.error, body.data);
|
|
},
|
|
|
|
/**
|
|
* Delete an attachment by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/attachment/${id}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* campaign is the API for campaign related operations.
|
|
* @type {Object}
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
campaign = {
|
|
/**
|
|
* @param {string} campaignID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
anonymize: async (campaignID) => {
|
|
return postJSON(this.getPath(`/campaign/${campaignID}/anonymize`));
|
|
},
|
|
|
|
/**
|
|
* @param {string} campaignID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
close: async (campaignID) => {
|
|
return postJSON(this.getPath(`/campaign/${campaignID}/close`));
|
|
},
|
|
|
|
/**
|
|
* @param {string} campaignID
|
|
* @returns
|
|
*/
|
|
exportEvents: async (campaignID) => {
|
|
window.open(this.getPath(`/campaign/${campaignID}/export/events`), '_blank');
|
|
},
|
|
|
|
/**
|
|
* Export campaign submissions as CSV
|
|
* @param {string} campaignID
|
|
* @returns
|
|
*/
|
|
exportSubmissions: async (campaignID) => {
|
|
window.open(this.getPath(`/campaign/${campaignID}/export/submissions`), '_blank');
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param {object} campaign
|
|
* @param {string} [campaign.companyID] uuid
|
|
* @param {string} campaign.templateID uuid
|
|
* @param {string} campaign.name
|
|
* @param {boolean} [campaign.saveSubmittedData]
|
|
* @param {boolean} [campaign.saveBrowserMetadata]
|
|
* @param {boolean} [campaign.isAnonymous]
|
|
* @param {boolean} [campaign.isTest]
|
|
* @param {boolean} [campaign.obfuscate]
|
|
* @param {string} campaign.sortField
|
|
* @param {string} campaign.sortOrder
|
|
* @param {string} campaign.sendStartAt
|
|
* @param {string} campaign.sendEndAt
|
|
* @param {string} [campaign.closeAt]
|
|
* @param {string} [campaign.anonymizeAt]
|
|
* @param {string} [campaign.scheduleAt]
|
|
* @param {string[]} campaign.recipientGroupIDs []uuid
|
|
* @param {string[]} campaign.allowDenyIDs []uuid
|
|
* @param {string} campaign.denyPageID uuid
|
|
* @param {string} campaign.evasionPageID uuid
|
|
* @param {Array} [campaign.webhooks] array of webhook configs
|
|
* @param {Array} [campaign.constraintWeekDays]
|
|
* @param {string} [campaign.constraintStartTime]
|
|
* @param {string} [campaign.constraintEndTime]
|
|
* @param {number} [campaign.jitterMin]
|
|
* @param {number} [campaign.jitterMax]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({
|
|
companyID,
|
|
templateID,
|
|
name,
|
|
saveSubmittedData,
|
|
saveBrowserMetadata,
|
|
isAnonymous,
|
|
isTest,
|
|
obfuscate,
|
|
sortField,
|
|
sortOrder,
|
|
sendStartAt,
|
|
sendEndAt,
|
|
closeAt,
|
|
anonymizeAt,
|
|
scheduleAt,
|
|
recipientGroupIDs,
|
|
allowDenyIDs,
|
|
denyPageID,
|
|
evasionPageID,
|
|
webhooks,
|
|
constraintWeekDays,
|
|
constraintStartTime,
|
|
constraintEndTime,
|
|
jitterMin,
|
|
jitterMax
|
|
}) => {
|
|
return await postJSON(this.getPath('/campaign'), {
|
|
companyID,
|
|
templateID,
|
|
name,
|
|
isAnonymous,
|
|
isTest,
|
|
obfuscate,
|
|
saveSubmittedData,
|
|
saveBrowserMetadata,
|
|
sortField,
|
|
sortOrder,
|
|
sendStartAt,
|
|
sendEndAt,
|
|
closeAt,
|
|
anonymizeAt,
|
|
scheduleAt,
|
|
recipientGroupIDs,
|
|
allowDenyIDs,
|
|
denyPageID,
|
|
evasionPageID,
|
|
webhooks,
|
|
constraintWeekDays,
|
|
constraintStartTime,
|
|
constraintEndTime,
|
|
jitterMin,
|
|
jitterMax
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {Object} campaign
|
|
* @param {string} campaign.id uuid
|
|
* @param {string} campaign.name
|
|
* @param {boolean} [campaign.saveSubmittedData]
|
|
* @param {boolean} [campaign.saveBrowserMetadata]
|
|
* @param {boolean} [campaign.isAnonymous]
|
|
* @param {boolean} [campaign.isTest]
|
|
* @param {boolean} [campaign.obfuscate]
|
|
* @param {string} campaign.sortField
|
|
* @param {string} campaign.sortOrder
|
|
* @param {string} campaign.sendStartAt
|
|
* @param {string} campaign.sendEndAt
|
|
* @param {string} [campaign.closeAt]
|
|
* @param {string} [campaign.anonymizeAt]
|
|
* @param {string} [campaign.scheduleAt]
|
|
* @param {string} campaign.templateID uuid
|
|
* @param {string[]} campaign.recipientGroupIDs []uuid
|
|
* @param {string[]} campaign.allowDenyIDs []uuid
|
|
* @param {string} campaign.denyPageID uuid
|
|
* @param {string} campaign.evasionPageID uuid
|
|
* @param {Array} [campaign.webhooks] array of webhook configs
|
|
* @param {Array} [campaign.constraintWeekDays]
|
|
* @param {string} [campaign.constraintStartTime]
|
|
* @param {string} [campaign.constraintEndTime]
|
|
* @param {number} [campaign.jitterMin]
|
|
* @param {number} [campaign.jitterMax]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async ({
|
|
id,
|
|
templateID,
|
|
name,
|
|
saveSubmittedData,
|
|
saveBrowserMetadata,
|
|
isAnonymous,
|
|
isTest,
|
|
obfuscate,
|
|
sortField,
|
|
sortOrder,
|
|
sendStartAt,
|
|
sendEndAt,
|
|
closeAt,
|
|
anonymizeAt,
|
|
scheduleAt,
|
|
recipientGroupIDs,
|
|
allowDenyIDs,
|
|
denyPageID,
|
|
evasionPageID,
|
|
webhooks,
|
|
constraintWeekDays,
|
|
constraintStartTime,
|
|
constraintEndTime,
|
|
jitterMin,
|
|
jitterMax
|
|
}) => {
|
|
return await postJSON(this.getPath(`/campaign/${id}`), {
|
|
templateID,
|
|
name,
|
|
isAnonymous,
|
|
isTest,
|
|
obfuscate,
|
|
saveSubmittedData,
|
|
saveBrowserMetadata,
|
|
sortField,
|
|
sortOrder,
|
|
sendStartAt,
|
|
sendEndAt,
|
|
closeAt,
|
|
anonymizeAt,
|
|
scheduleAt,
|
|
recipientGroupIDs,
|
|
allowDenyIDs,
|
|
denyPageID,
|
|
evasionPageID,
|
|
webhooks,
|
|
constraintWeekDays,
|
|
constraintStartTime,
|
|
constraintEndTime,
|
|
jitterMin,
|
|
jitterMax
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get a campaign by ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/campaign/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get a campaign by name.
|
|
*
|
|
* @param {string} name
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByName: async (name, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/campaign/name/${name}?${appendQuery(null)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all campaigns using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/campaign?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all campaigns using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string} start RFC3339NANO
|
|
* @param {string} end RFC3339NANO
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getWithinDates: async (start, end, options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/campaign/calendar?${appendQuery(options)}${this.appendCompanyQuery(companyID)}&start=${start}&end=${end}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all active campaigns using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllActive: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/campaign/active?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all upcoming campaigns using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllUpcoming: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/campaign/upcoming?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all active campaigns using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllFinished: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/campaign/finished?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all campaign recipients.
|
|
*
|
|
* @param {string} campaignID
|
|
* @param {TableURLParams} options
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllCampaignRecipients: async (campaignID, options) => {
|
|
return await getJSON(
|
|
this.getPath(`/campaign/${campaignID}/recipients?${appendQuery(options)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all event types.
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllEventTypes: async () => {
|
|
return await getJSON(this.getPath(`/campaign/event-types`));
|
|
},
|
|
|
|
/**
|
|
* Get all events by campaign ID.
|
|
*
|
|
* @param {string} campaignID
|
|
* @param {TableURLParams} options
|
|
* @param {string} since RFC3339NANO
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllEventsByCampaignID: async (campaignID, options, since = '') => {
|
|
return await getJSON(
|
|
this.getPath(`/campaign/${campaignID}/events?${appendQuery(options)}&since=${since}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all events across campaigns.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllEvents: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/campaign/events?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get campaigns stats
|
|
* if no company ID is provided it retrieves the global stats including all companies
|
|
*/
|
|
getStats: async (companyID = null, options = {}) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/campaign/statistics?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get campaign result stats
|
|
* @param {string} campaignID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getResultStats: async (campaignID) => {
|
|
return await getJSON(this.getPath(`/campaign/${campaignID}/statistics`));
|
|
},
|
|
|
|
/**
|
|
* Get campaign recipient email.
|
|
*
|
|
* @param {string} campaignRecipientID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getEmail: async (campaignRecipientID) => {
|
|
return await getJSON(this.getPath(`/campaign/recipient/${campaignRecipientID}/email`));
|
|
},
|
|
|
|
/**
|
|
* Set email sent to now
|
|
*
|
|
* @param {string} campaignRecipient
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
setEmailSent: async (campaignRecipient) => {
|
|
return await postJSON(this.getPath(`/campaign/recipient/${campaignRecipient}/sent`));
|
|
},
|
|
|
|
/**
|
|
* Send message to campaign recipient (works for both email and API senders)
|
|
*
|
|
* @param {string} campaignRecipientID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
sendMessage: async (campaignRecipientID) => {
|
|
return await postJSON(this.getPath(`/campaign/recipient/${campaignRecipientID}/send`));
|
|
},
|
|
|
|
/**
|
|
* Send email to campaign recipient (alias for sendMessage for backward compatibility)
|
|
*
|
|
* @param {string} campaignRecipientID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
sendEmail: async (campaignRecipientID) => {
|
|
return await postJSON(this.getPath(`/campaign/recipient/${campaignRecipientID}/send`));
|
|
},
|
|
|
|
/**
|
|
* Get campaign recipient landingpage URL.
|
|
*
|
|
* @param {string} campaignRecipientID
|
|
* @return {Promise<ApiResponse>}
|
|
*/
|
|
getURL: async (campaignRecipientID) => {
|
|
return await getJSON(this.getPath(`/campaign/recipient/${campaignRecipientID}/url`));
|
|
},
|
|
|
|
/**
|
|
* Delete all device codes for a campaign so every recipient gets a fresh
|
|
* code (and picks up any proxy change) on their next page visit.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
deleteDeviceCodes: async (id) => {
|
|
return await deleteJSON(this.getPath(`/campaign/${id}/device-codes`));
|
|
},
|
|
|
|
/**
|
|
* Delete a campaign.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/campaign/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Delete a campaign event.
|
|
*
|
|
* @param {string} eventID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
deleteEvent: async (eventID) => {
|
|
return await deleteJSON(this.getPath(`/campaign/event/${eventID}`));
|
|
},
|
|
|
|
/**
|
|
* Get campaign statistics by campaign ID.
|
|
*
|
|
* @param {string} campaignID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getCampaignStats: async (campaignID) => {
|
|
return await getJSON(this.getPath(`/campaign/${campaignID}/stats`));
|
|
},
|
|
|
|
/**
|
|
* Get all campaign statistics.
|
|
*
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllCampaignStats: async (companyID = null) => {
|
|
const companyQuery = companyID ? `?${this.companyQuery(companyID)}` : '';
|
|
return await getJSON(this.getPath(`/campaign/stats/all${companyQuery}`));
|
|
},
|
|
|
|
/**
|
|
* Get all manual campaign statistics (those without campaignID).
|
|
*
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getManualCampaignStats: async (companyID = null) => {
|
|
const companyQuery = companyID ? `?${this.companyQuery(companyID)}` : '';
|
|
return await getJSON(this.getPath(`/campaign/stats/manual${companyQuery}`));
|
|
},
|
|
|
|
/**
|
|
* Create manual campaign statistics.
|
|
*
|
|
* @param {object} stats
|
|
* @param {string} stats.campaignName
|
|
* @param {string} [stats.companyId]
|
|
* @param {number} stats.totalRecipients
|
|
* @param {number} stats.emailsSent
|
|
* @param {number} stats.trackingPixelLoaded
|
|
* @param {number} stats.websiteVisits
|
|
* @param {number} stats.dataSubmissions
|
|
* @param {number} stats.reported
|
|
* @param {string} [stats.templateName]
|
|
* @param {string} [stats.campaignType]
|
|
* @param {string} [stats.campaignStartDate] - ISO date string
|
|
* @param {string} [stats.campaignEndDate] - ISO date string
|
|
* @param {string} [stats.campaignClosedAt] - ISO date string
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
createStats: async (stats) => {
|
|
return await postJSON(this.getPath('/campaign/stats'), stats);
|
|
},
|
|
|
|
/**
|
|
* Update manual campaign statistics by ID.
|
|
*
|
|
* @param {string} statsID
|
|
* @param {object} stats
|
|
* @param {string} stats.campaignName
|
|
* @param {string} [stats.companyId]
|
|
* @param {number} stats.totalRecipients
|
|
* @param {number} stats.emailsSent
|
|
* @param {number} stats.trackingPixelLoaded
|
|
* @param {number} stats.websiteVisits
|
|
* @param {number} stats.dataSubmissions
|
|
* @param {number} stats.reported
|
|
* @param {string} [stats.templateName]
|
|
* @param {string} [stats.campaignType]
|
|
* @param {string} [stats.campaignStartDate] - ISO date string
|
|
* @param {string} [stats.campaignEndDate] - ISO date string
|
|
* @param {string} [stats.campaignClosedAt] - ISO date string
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
updateStats: async (statsID, stats) => {
|
|
return await putJSON(this.getPath(`/campaign/stats/${statsID}`), stats);
|
|
},
|
|
|
|
/**
|
|
* Delete manual campaign statistics by ID.
|
|
*
|
|
* @param {string} statsID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
deleteStats: async (statsID) => {
|
|
return await deleteJSON(this.getPath(`/campaign/stats/${statsID}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* campain templates is the API for campaign template related operations.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
campaignTemplate = {
|
|
/**
|
|
* Get a campaign template by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @param {boolean} full retrieve related data
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id, full = false) => {
|
|
let p = this.getPath(`/campaign/template/${id}`);
|
|
if (full) {
|
|
p += '?full';
|
|
}
|
|
return await getJSON(p);
|
|
},
|
|
|
|
/**
|
|
* Get all campaign templates using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null, usableOnly = false) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/campaign/template?${appendQuery(options)}${this.appendCompanyQuery(companyID)}&usableOnly=${usableOnly}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Create a new campaign template.
|
|
*
|
|
* @param {object} template
|
|
* @param {string} template.name
|
|
* @param {string} template.companyID
|
|
* @param {string} template.domainID
|
|
* @param {string} template.beforeLandingPageID
|
|
* @param {string} template.beforeLandingProxyID
|
|
* @param {string} template.afterLandingPageID
|
|
* @param {string} template.afterLandingProxyID
|
|
* @param {string} template.landingPageID
|
|
* @param {string} template.landingProxyID
|
|
* @param {string} template.smtpConfigurationID
|
|
* @param {string} template.apiSenderID
|
|
* @param {string} template.afterLandingPageRedirectURL
|
|
* @param {string} template.urlIdentifierID
|
|
* @param {string} template.stateIdentifierID
|
|
* @param {string} template.urlPath
|
|
* @param {string} template.emailID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({
|
|
name,
|
|
companyID,
|
|
domainID,
|
|
beforeLandingPageID,
|
|
beforeLandingProxyID,
|
|
afterLandingPageID,
|
|
afterLandingProxyID,
|
|
landingPageID,
|
|
landingProxyID,
|
|
smtpConfigurationID,
|
|
apiSenderID,
|
|
urlIdentifierID,
|
|
stateIdentifierID,
|
|
afterLandingPageRedirectURL,
|
|
emailID: emailID,
|
|
urlPath: urlPath
|
|
}) => {
|
|
return await postJSON(this.getPath('/campaign/template'), {
|
|
name: name,
|
|
companyID: companyID,
|
|
domainID: domainID,
|
|
beforeLandingPageID: beforeLandingPageID,
|
|
beforeLandingProxyID: beforeLandingProxyID,
|
|
afterLandingPageID: afterLandingPageID,
|
|
afterLandingProxyID: afterLandingProxyID,
|
|
landingPageID: landingPageID,
|
|
landingProxyID: landingProxyID,
|
|
smtpConfigurationID: smtpConfigurationID,
|
|
apiSenderID: apiSenderID,
|
|
afterLandingPageRedirectURL: afterLandingPageRedirectURL,
|
|
urlIdentifierID: urlIdentifierID,
|
|
stateIdentifierID: stateIdentifierID,
|
|
emailID: emailID,
|
|
urlPath: urlPath
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Update a campaign template.
|
|
*
|
|
* @param {Object} template
|
|
* @param {string} template.id
|
|
* @param {string} template.name
|
|
* @param {string} template.companyID
|
|
* @param {string} template.domainID
|
|
* @param {string} template.beforeLandingPageID
|
|
* @param {string} template.beforeLandingProxyID
|
|
* @param {string} template.afterLandingPageID
|
|
* @param {string} template.afterLandingProxyID
|
|
* @param {string} template.landingPageID
|
|
* @param {string} template.landingProxyID
|
|
* @param {string} template.smtpConfigurationID
|
|
* @param {string} template.apiSenderID
|
|
* @param {string} template.afterLandingPageRedirectURL
|
|
* @param {string} template.emailID
|
|
* @param {string} template.urlIdentifierID
|
|
* @param {string} template.stateIdentifierID
|
|
* @param {string} template.urlPath
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async ({
|
|
id,
|
|
name,
|
|
companyID,
|
|
domainID,
|
|
beforeLandingPageID,
|
|
beforeLandingProxyID,
|
|
afterLandingPageID,
|
|
afterLandingProxyID,
|
|
landingPageID,
|
|
landingProxyID,
|
|
smtpConfigurationID,
|
|
apiSenderID,
|
|
afterLandingPageRedirectURL,
|
|
emailID: emailID,
|
|
urlIdentifierID: urlIdentifierID,
|
|
stateIdentifierID: stateIdentifierID,
|
|
urlPath: urlPath
|
|
}) => {
|
|
return await postJSON(this.getPath(`/campaign/template/${id}`), {
|
|
name: name,
|
|
companyID: companyID,
|
|
domainID: domainID,
|
|
beforeLandingPageID: beforeLandingPageID,
|
|
beforeLandingProxyID: beforeLandingProxyID,
|
|
afterLandingPageID: afterLandingPageID,
|
|
afterLandingProxyID: afterLandingProxyID,
|
|
landingPageID: landingPageID,
|
|
landingProxyID: landingProxyID,
|
|
smtpConfigurationID: smtpConfigurationID,
|
|
apiSenderID: apiSenderID,
|
|
afterLandingPageRedirectURL: afterLandingPageRedirectURL,
|
|
emailID: emailID,
|
|
urlIdentifierID: urlIdentifierID,
|
|
stateIdentifierID: stateIdentifierID,
|
|
urlPath: urlPath
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete a campaign template.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/campaign/template/${id}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* company is the API for company related operations.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
company = {
|
|
/**
|
|
* Get a company by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/company/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Exports a companies data
|
|
*
|
|
* @param {string} id
|
|
* @returns
|
|
*/
|
|
export: async (id) => {
|
|
window.open(this.getPath(`/company/${id ? id : 'shared'}/export`), '_blank');
|
|
},
|
|
|
|
/**
|
|
* Get all companies using pagination
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options) => {
|
|
return await getJSON(this.getPath(`/company?${appendQuery(options)}`));
|
|
},
|
|
|
|
/**
|
|
* Create a new company.
|
|
*
|
|
* @param {string} name
|
|
* @param {string} comment
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async (name, comment) => {
|
|
return await postJSON(this.getPath(`/company`), {
|
|
name: name,
|
|
comment: comment
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Update a company.
|
|
*
|
|
* @param {string} id
|
|
* @param {string} name
|
|
* @param {string} comment
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async (id, name, comment) => {
|
|
return await postJSON(this.getPath(`/company/${id}`), {
|
|
name: name,
|
|
comment: comment
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete a company.
|
|
*
|
|
* @param {string} id
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/company/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get the auto-prune orphaned recipients setting for a company.
|
|
* Returns only the per-company enabled flag.
|
|
*
|
|
* @param {string} id - company ID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAutoPrune: async (id) => {
|
|
return await getJSON(this.getPath(`/company/${id}/option/auto-prune`));
|
|
},
|
|
|
|
/**
|
|
* Set the auto-prune orphaned recipients setting for a company.
|
|
*
|
|
* @param {string} id - company ID
|
|
* @param {boolean} enabled
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
setAutoPrune: async (id, enabled) => {
|
|
return await postJSON(this.getPath(`/company/${id}/option/auto-prune`), {
|
|
enabled: enabled
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* domain is the API for domain related operations.
|
|
*/
|
|
domain = {
|
|
/**
|
|
* creates a new domain.
|
|
*
|
|
* @param {object} domain
|
|
* @param {string} domain.name
|
|
* @param {string} domain.type
|
|
* @param {string} domain.proxyTargetDomain
|
|
* @param {boolean} domain.managedTLS
|
|
* @param {boolean} domain.ownManagedTLS
|
|
* @param {boolean} domain.selfSignedTLS
|
|
* @param {string} domain.ownManagedTLSKey
|
|
* @param {string} domain.ownManagedTLSPem
|
|
* @param {boolean} domain.hostWebsite
|
|
* @param {string} domain.pageContent
|
|
* @param {string} domain.pageNotFoundContent
|
|
* @param {string} domain.redirectURL
|
|
* @param {string} domain.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({
|
|
name,
|
|
type,
|
|
proxyTargetDomain,
|
|
managedTLS,
|
|
ownManagedTLS,
|
|
selfSignedTLS,
|
|
ownManagedTLSKey,
|
|
ownManagedTLSPem,
|
|
hostWebsite,
|
|
pageContent,
|
|
pageNotFoundContent,
|
|
redirectURL,
|
|
companyID
|
|
}) => {
|
|
return await postJSON(this.getPath('/domain/'), {
|
|
name: name,
|
|
type: type,
|
|
proxyTargetDomain: proxyTargetDomain,
|
|
managedTLS: managedTLS,
|
|
ownManagedTLS: ownManagedTLS,
|
|
selfSignedTLS: selfSignedTLS,
|
|
ownManagedTLSKey: ownManagedTLSKey,
|
|
ownManagedTLSPem: ownManagedTLSPem,
|
|
hostWebsite: hostWebsite,
|
|
pageContent: pageContent,
|
|
pageNotFoundContent: pageNotFoundContent,
|
|
redirectURL: redirectURL,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* updates a domain.
|
|
*
|
|
* @param {object} domain
|
|
* @param {string} domain.id
|
|
* @param {string} [domain.type]
|
|
* @param {string} [domain.proxyTargetDomain]
|
|
* @param {boolean} domain.managedTLS
|
|
* @param {boolean} domain.ownManagedTLS
|
|
* @param {boolean} domain.selfSignedTLS
|
|
* @param {string} domain.ownManagedTLSKey
|
|
* @param {string} domain.ownManagedTLSPem
|
|
* @param {boolean} [domain.hostWebsite]
|
|
* @param {string} [domain.pageContent]
|
|
* @param {string} [domain.pageNotFoundContent]
|
|
* @param {string} [domain.redirectURL]
|
|
* @param {string} domain.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async ({
|
|
id,
|
|
type,
|
|
proxyTargetDomain,
|
|
managedTLS,
|
|
ownManagedTLS,
|
|
selfSignedTLS,
|
|
ownManagedTLSKey,
|
|
ownManagedTLSPem,
|
|
hostWebsite,
|
|
pageContent,
|
|
pageNotFoundContent,
|
|
redirectURL,
|
|
companyID
|
|
}) => {
|
|
const payload = {
|
|
managedTLS: managedTLS,
|
|
ownManagedTLS: ownManagedTLS,
|
|
selfSignedTLS: selfSignedTLS,
|
|
ownManagedTLSKey: ownManagedTLSKey,
|
|
ownManagedTLSPem: ownManagedTLSPem,
|
|
companyID: companyID
|
|
};
|
|
|
|
// conditionally add fields if they are provided
|
|
if (type !== undefined) payload.type = type;
|
|
if (proxyTargetDomain !== undefined) payload.proxyTargetDomain = proxyTargetDomain;
|
|
if (hostWebsite !== undefined) payload.hostWebsite = hostWebsite;
|
|
if (pageContent !== undefined) payload.pageContent = pageContent;
|
|
if (pageNotFoundContent !== undefined) payload.pageNotFoundContent = pageNotFoundContent;
|
|
if (redirectURL !== undefined) payload.redirectURL = redirectURL;
|
|
|
|
return await postJSON(this.getPath(`/domain/${id}`), payload);
|
|
},
|
|
|
|
/**
|
|
* deletes a domain.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteReq(this.getPath(`/domain/${id}`));
|
|
},
|
|
|
|
/**
|
|
* gets a domain by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/domain/${id}`));
|
|
},
|
|
|
|
/**
|
|
* get a domain by its name.
|
|
*
|
|
* @param {string} name
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByName: async (name) => {
|
|
return await getJSON(this.getPath(`/domain/name/${name}`));
|
|
},
|
|
|
|
/**
|
|
* get domains
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/domain?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* get domains subsets
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllSubset: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/domain/subset?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* get domains subsets excluding proxy domains
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllSubsetWithoutProxies: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/domain/subset/noproxies?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* page s the API for page related operations.
|
|
*/
|
|
page = {
|
|
/**
|
|
* Get a page by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/page/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get all pages using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/page?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get page content by id
|
|
*/
|
|
getContentByID: async (id) => {
|
|
return await getJSON(this.getPath(`/page/${id}/content`));
|
|
},
|
|
|
|
/**
|
|
* Get all pages using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getOverviews: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/page/overview?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Create a new page.
|
|
*
|
|
* @param {string} name
|
|
* @param {string} content
|
|
* @param {string} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async (name, content, companyID) => {
|
|
const payload = {
|
|
name: name,
|
|
content: content,
|
|
companyID: companyID
|
|
};
|
|
return await postJSON(this.getPath('/page'), payload);
|
|
},
|
|
|
|
/**
|
|
* Update a page.
|
|
*
|
|
* @param {string} id
|
|
* @param {object} page
|
|
* @param {string} page.name
|
|
* @param {string} page.content
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async (id, page) => {
|
|
return await patchJSON(this.getPath(`/page/${id}`), page);
|
|
},
|
|
|
|
/**
|
|
* Delete a page.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/page/${id}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* log is the API for log related operations.
|
|
*/
|
|
log = {
|
|
/**
|
|
* Get the log level.
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getLevel: async () => {
|
|
return await getJSON(this.getPath('/log'));
|
|
},
|
|
|
|
/**
|
|
* Set the log level.
|
|
*
|
|
* @param {string} level
|
|
* @param {string} dbLevel
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
setLevel: async (level, dbLevel) => {
|
|
return await postJSON(this.getPath('/log'), {
|
|
level: level,
|
|
dbLevel: dbLevel
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Test the log levels. Can only be observed in the backend logs.
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
testLevels: async () => {
|
|
return await getJSON(this.getPath('/log/test'));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* email is the API for email related operations.
|
|
*/
|
|
email = {
|
|
/**
|
|
* Add attachments to a email.
|
|
*
|
|
* @param {string} emailID
|
|
* @param {Array<{id: string, isInline: boolean}>} attachments - Array of attachment objects with id and isInline flag
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
addAttachments: async (emailID, attachments) => {
|
|
return await postJSON(this.getPath(`/email/${emailID}/attachment`), {
|
|
attachments: attachments
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Remove an attachment from a email.
|
|
*
|
|
* @param {string} emailID
|
|
* @param {string} attachmentID
|
|
* @returns
|
|
*/
|
|
removeAttachment: async (emailID, attachmentID) => {
|
|
return await deleteJSON(this.getPath(`/email/${emailID}/attachment`), {
|
|
attachmentID: attachmentID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get a email by ID.
|
|
*
|
|
* @param {string} id
|
|
* @param {string|null} [companyID]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id, companyID = null) => {
|
|
const companyQuery = companyID ? `?${this.companyQuery(companyID)}` : '';
|
|
return await getJSON(this.getPath(`/email/${id}${companyQuery}`));
|
|
},
|
|
|
|
/**
|
|
* Get the content of a email by ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getContentByID: async (id) => {
|
|
return await getJSON(this.getPath(`/email/${id}/content`));
|
|
},
|
|
|
|
/**
|
|
* Get all emails using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/email?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all email overviews
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getOverviews: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/email/overview?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Send a test email
|
|
*
|
|
*
|
|
* @param {object} params
|
|
* @param {string} params.id
|
|
* @param {string} params.smtpID
|
|
* @param {string} params.domainID
|
|
* @param {string} params.recipientID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
sendTest: async ({ id: emailID, smtpID, domainID, recipientID }) => {
|
|
return await postJSON(this.getPath(`/email/${emailID}/send-test`), {
|
|
smtpID: smtpID,
|
|
recipientID: recipientID,
|
|
domainID: domainID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Create a new email.
|
|
*
|
|
* @param {Object} email
|
|
* @param {string} email.name
|
|
* @param {string} email.content
|
|
* @param {string} email.mailEnvelopeFrom
|
|
* @param {string} email.mailHeaderFrom
|
|
* @param {string} email.mailHeaderSubject
|
|
* @param {bool} email.addTrackingPixel
|
|
* @param {string} [email.companyID]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async (email) => {
|
|
return await postJSON(this.getPath('/email'), email);
|
|
},
|
|
|
|
/**
|
|
* Update a email.
|
|
*
|
|
* @param {Object} email
|
|
* @param {string} email.id
|
|
* @param {string} [email.name]
|
|
* @param {string} [email.content]
|
|
* @param {string} [email.mailEnvelopeFrom]
|
|
* @param {string} [email.mailHeaderFrom]
|
|
* @param {string} [email.mailHeaderSubject]
|
|
* @param {boolean} [email.addTrackingPixel]
|
|
* @param {string} [email.companyID]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async ({
|
|
id,
|
|
name,
|
|
content,
|
|
mailEnvelopeFrom,
|
|
mailHeaderFrom,
|
|
mailHeaderSubject,
|
|
addTrackingPixel,
|
|
companyID
|
|
}) => {
|
|
return await postJSON(this.getPath(`/email/${id}`), {
|
|
name: name,
|
|
content: content,
|
|
mailEnvelopeFrom: mailEnvelopeFrom,
|
|
mailHeaderSubject: mailHeaderSubject,
|
|
mailHeaderFrom: mailHeaderFrom,
|
|
addTrackingPixel: addTrackingPixel,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete a email.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/email/${id}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* session is the API for session related operations.
|
|
*/
|
|
session = {
|
|
/**
|
|
* Ping session.
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
ping: async () => {
|
|
return await getJSON(this.getPath(`/session/ping`));
|
|
},
|
|
|
|
/**
|
|
* Revoke a session.
|
|
*
|
|
* @param {string} sessionID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
revoke: async (sessionID) => {
|
|
return await deleteReq(this.getPath(`/session/${sessionID}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* smtpConfiguration is the API for SMTPConfiguration related operations.
|
|
*/
|
|
smtpConfiguration = {
|
|
/**
|
|
* Get all SMTPConfigurations using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/smtp-configuration?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get a SMTPConfiguration by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/smtp-configuration/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Send a test email using the configuration.
|
|
*
|
|
* @param {string} id
|
|
* @param {Object} data
|
|
* @param {string} data.email
|
|
* @param {string} data.mailFrom
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
sendTestEmail: async (id, data) => {
|
|
return await postJSON(this.getPath(`/smtp-configuration/${id}/test-email`), data);
|
|
},
|
|
|
|
/**
|
|
* Create a new SMTPConfiguration.
|
|
*
|
|
* @param {Object} configuration
|
|
* @param {string} configuration.name
|
|
* @param {string} configuration.host
|
|
* @param {number} configuration.port
|
|
* @param {string} configuration.username
|
|
* @param {string} configuration.password
|
|
* @param {boolean} configuration.ignoreCertErrors
|
|
* @param {string} configuration.companyID
|
|
* @returns
|
|
*/
|
|
create: async (configuration) => {
|
|
return await postJSON(this.getPath('/smtp-configuration'), configuration);
|
|
},
|
|
|
|
/**
|
|
* Update a SMTPConfiguration.
|
|
*
|
|
* @param {Object} configuration
|
|
* @param {string} configuration.id
|
|
* @param {string} configuration.name
|
|
* @param {string} configuration.host
|
|
* @param {number} configuration.port
|
|
* @param {string} configuration.username
|
|
* @param {string} configuration.password
|
|
* @param {boolean} configuration.ignoreCertErrors
|
|
* @param {string} configuration.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async (configuration) => {
|
|
return await patchJSON(
|
|
this.getPath(`/smtp-configuration/${configuration.id}`),
|
|
configuration
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Delete a SMTPConfiguration.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/smtp-configuration/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Add a new SMTP header to a SMTPConfiguration.
|
|
*
|
|
* @param {string} smtpConfigurationID
|
|
* @param {string} key
|
|
* @param {string} value
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
addHeader: async (smtpConfigurationID, key, value) => {
|
|
return await patchJSON(this.getPath(`/smtp-configuration/${smtpConfigurationID}/header`), {
|
|
key: key,
|
|
value: value
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete a SMTP header from a SMTPConfiguration.
|
|
*
|
|
* @param {string} smtpConfigurationID
|
|
* @param {string} headerID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
deleteHeader: async (smtpConfigurationID, headerID) => {
|
|
return await deleteJSON(
|
|
this.getPath(`/smtp-configuration/${smtpConfigurationID}/header/${headerID}`)
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* oauthProvider is the API for OAuth Provider related operations.
|
|
*/
|
|
oauthProvider = {
|
|
/**
|
|
* Get all OAuth Providers using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID) => {
|
|
return await getJSON(
|
|
this.getPath(`/oauth-provider?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get an OAuth Provider by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/oauth-provider/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Create a new OAuth Provider.
|
|
*
|
|
* @param {Object} provider
|
|
* @param {string} provider.name
|
|
* @param {string} provider.clientID
|
|
* @param {string} provider.clientSecret
|
|
* @param {string} provider.authURL
|
|
* @param {string} provider.tokenURL
|
|
* @param {string} provider.scopes
|
|
* @param {string} provider.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async (provider) => {
|
|
return await postJSON(this.getPath('/oauth-provider'), provider);
|
|
},
|
|
|
|
/**
|
|
* Update an OAuth Provider.
|
|
*
|
|
* @param {Object} provider
|
|
* @param {string} provider.id
|
|
* @param {string} provider.name
|
|
* @param {string} provider.clientID
|
|
* @param {string} provider.clientSecret
|
|
* @param {string} provider.authURL
|
|
* @param {string} provider.tokenURL
|
|
* @param {string} provider.scopes
|
|
* @param {string} provider.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async (provider) => {
|
|
return await patchJSON(this.getPath(`/oauth-provider/${provider.id}`), provider);
|
|
},
|
|
|
|
/**
|
|
* Delete an OAuth Provider.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/oauth-provider/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get the authorization URL for an OAuth Provider.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAuthorizationURL: async (id) => {
|
|
return await getJSON(this.getPath(`/oauth-authorize/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Remove authorization tokens from an OAuth Provider.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
removeAuthorization: async (id) => {
|
|
return await postJSON(this.getPath(`/oauth-provider/${id}/remove-authorization`), {});
|
|
},
|
|
|
|
/**
|
|
* Import authorized OAuth tokens.
|
|
*
|
|
* @param {Array<{access_token: string, refresh_token: string, client_id: string, expires_at: number, name: string, user: string, scope: string, token_url?: string, created_at?: number}>} tokens
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
importTokens: async (tokens) => {
|
|
return await postJSON(this.getPath('/oauth-provider/import-tokens'), tokens);
|
|
},
|
|
|
|
/**
|
|
* Export OAuth tokens for a provider.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
exportTokens: async (id) => {
|
|
return await getJSON(this.getPath(`/oauth-provider/${id}/export-tokens`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* user is the API for user related operations - these actions also affect the user's sessions
|
|
*/
|
|
user = {
|
|
/**
|
|
* Create a new user
|
|
*
|
|
* @param {Object} user
|
|
* @param {string} user.username
|
|
* @param {string} user.password
|
|
* @param {string} user.email
|
|
* @param {string} user.fullname
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({ username, password, email, fullname }) => {
|
|
return await postJSON(this.getPath(`/user`), {
|
|
username,
|
|
password,
|
|
email,
|
|
fullname
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete a user by ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/user/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get all users using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options) => {
|
|
return await getJSON(this.getPath(`/user?${appendQuery(options)}`));
|
|
},
|
|
|
|
/**
|
|
* Get a user by ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
* */
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/user/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get user's sessions.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllSessions: async (options) => {
|
|
return await getJSON(this.getPath(`/user/sessions?${appendQuery(options)}`));
|
|
},
|
|
|
|
/**
|
|
* Update a user.
|
|
*
|
|
* @param {Object} user
|
|
* @param {string} user.id
|
|
* @param {string} user.username
|
|
* @param {string} user.email
|
|
* @param {string} user.fullname
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
updateByID: async ({ id, username, email, fullname }) => {
|
|
return await postJSON(this.getPath(`/user/${id}`), {
|
|
username: username,
|
|
email: email,
|
|
name: fullname
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get user's api key in a masked format.
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAPIKeyMasked: async () => {
|
|
return await getJSON(this.getPath(`/user/api`));
|
|
},
|
|
|
|
/**
|
|
* Upsert the logged-in users api key
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
upsertAPIKey: async () => {
|
|
return await postJSON(this.getPath(`/user/api`), {});
|
|
},
|
|
|
|
/**
|
|
* Removes the logged-in users api key
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
removeAPIKey: async () => {
|
|
return await deleteJSON(this.getPath(`/user/api`), {});
|
|
},
|
|
|
|
/**
|
|
* Login.
|
|
*
|
|
* @param {string} username
|
|
* @param {string} password
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
login: async (username, password) => {
|
|
return await postJSON(this.getPath(`/user/login`), {
|
|
username,
|
|
password
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Login with TOTP MFA.
|
|
*
|
|
* @param {string} username
|
|
* @param {string} password
|
|
* @param {string} token
|
|
* @returns {Promise<ApiResponse>}
|
|
* */
|
|
loginTOTP: async (username, password, token) => {
|
|
return await postJSON(this.getPath(`/user/login`), {
|
|
username,
|
|
password,
|
|
totp: token
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Login with MFA recovery code.
|
|
*
|
|
* @param {string} username
|
|
* @param {string} password
|
|
* @param {string} recoveryCode
|
|
* @returns {Promise<ApiResponse>}
|
|
* */
|
|
loginMFARecoveryCode: async (username, password, recoveryCode) => {
|
|
return await postJSON(this.getPath(`/user/login`), {
|
|
username,
|
|
password,
|
|
totp: '',
|
|
recoveryCode: recoveryCode
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Log out.
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
logout: async () => {
|
|
return await postJSON(this.getPath(`/user/logout`));
|
|
},
|
|
|
|
/**
|
|
* Change the user's username
|
|
*
|
|
* @param {string} newUsername
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
changeUsername: async (newUsername) => {
|
|
return await postJSON(this.getPath(`/user/username`), {
|
|
username: newUsername
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Change the user's full name
|
|
*
|
|
* @param {string} newFullname
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
changeFullname: async (newFullname) => {
|
|
return await postJSON(this.getPath(`/user/fullname`), {
|
|
fullname: newFullname
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Change the user's password
|
|
*
|
|
* @param {string} currentPassword
|
|
* @param {string} newPassword
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
changePassword: async (currentPassword, newPassword) => {
|
|
return await postJSON(this.getPath(`/user/password`), {
|
|
currentPassword,
|
|
newPassword
|
|
});
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param {string} password
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
setupTOTPMFA: async (password) => {
|
|
return await postJSON(this.getPath(`/user/mfa/totp/setup`), {
|
|
password: password
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Verify TOTP MFA setup
|
|
*
|
|
* @param {string} token
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
setupVerifyTOTPMFA: async (token) => {
|
|
return await postJSON(this.getPath(`/user/mfa/totp/setup/verify`), {
|
|
token: token
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Check if TOTP MFA is enabled
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
isTOTPMFAEnabled: async () => {
|
|
return await getJSON(this.getPath(`/user/mfa/totp`));
|
|
},
|
|
|
|
/**
|
|
* Verify TOTP MFA
|
|
*
|
|
* @param {string} token
|
|
* @returns
|
|
*/
|
|
verifyTOTPMFA: async (token) => {
|
|
return await postJSON(this.getPath(`/user/mfa/totp/verify`), {
|
|
token: token
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Disable TOTP MFA
|
|
* Requires the TOTP token to complete
|
|
*
|
|
* @param {string} totpToken
|
|
* @returns
|
|
*/
|
|
disableTOTPMFA: async (totpToken = '') => {
|
|
return await postJSON(this.getPath(`/user/mfa/totp`), {
|
|
token: totpToken
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Disable TOTP MFA
|
|
* Requires the TOTP token to complete
|
|
*
|
|
* @param {string} userID
|
|
* @returns
|
|
*/
|
|
invalidateSessions: async (userID = '') => {
|
|
if (userID) {
|
|
return await postJSON(this.getPath(`/user/sessions/invalidate`), { userID });
|
|
}
|
|
const res = await fetch(this.getPath(`/user/sessions/invalidate`), {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
}
|
|
});
|
|
let body = {};
|
|
try {
|
|
body = await res.json();
|
|
} catch (e) {
|
|
body = {
|
|
success: false,
|
|
error: 'invalid JSON in response'
|
|
};
|
|
}
|
|
return newResponse(body.success, res.status, body.error, body.data);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* option is the API settings.
|
|
*/
|
|
option = {
|
|
/**
|
|
* Get setting by key.
|
|
*
|
|
* @param {'is_installed'|'max_file_upload_size_mb'|'repeat_offender_months'|'sso_login'|'display_mode'|'obfuscation_template'} key
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
get: async (key) => {
|
|
return await getJSON(this.getPath(`/option/${key}`));
|
|
},
|
|
|
|
/**
|
|
* Get the global auto-prune orphaned recipients setting.
|
|
* Returns the full option including per-company entries.
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAutoPrune: async () => {
|
|
return await getJSON(this.getPath(`/option/auto-prune`));
|
|
},
|
|
|
|
/**
|
|
* Set the global auto-prune orphaned recipients setting.
|
|
* The full option object (including per-company entries) must be supplied.
|
|
*
|
|
* @param {{ enabled: boolean, companies?: string[] }} option
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
setAutoPrune: async (option) => {
|
|
return await postJSON(this.getPath(`/option/auto-prune`), option);
|
|
},
|
|
|
|
/**
|
|
* Set setting by key and value.
|
|
*
|
|
* @param {'max_file_upload_size_mb'|'repeat_offender_months'|'sso_login'|'display_mode'|'obfuscation_template'} key
|
|
* @param {string} value
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
set: async (key, value) => {
|
|
return await postJSON(this.getPath(`/option`), {
|
|
key: key,
|
|
value: value
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* log is the API for log related operations.
|
|
*/
|
|
recipient = {
|
|
/**
|
|
* Get all recipients using pagination.
|
|
*
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
countRepeatOffenders: async (companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/recipient/repeat-offenders?${appendQuery(null)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all recipients using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/recipient?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all orphaned recipients (recipients not in any group) using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getOrphaned: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/recipient/orphaned?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Delete all orphaned recipients (recipients not in any group).
|
|
*
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
deleteAllOrphaned: async (companyID = null) => {
|
|
return await deleteReq(
|
|
this.getPath(`/recipient/orphaned/delete?${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get campaign events related by recipient id and optional campaign id
|
|
*
|
|
* @param {string} recipientID
|
|
* @param {TableURLParams} options
|
|
* @param {string} [campaignID]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getEvents: async (recipientID, options, campaignID) => {
|
|
let path = `/recipient/${recipientID}/events?${appendQuery(options)}`;
|
|
if (campaignID) {
|
|
path += `&campaignID=${campaignID}`;
|
|
}
|
|
return await getJSON(this.getPath(path));
|
|
},
|
|
|
|
/**
|
|
* Get a recipient stats by ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getStatsByID: async (id) => {
|
|
return await getJSON(this.getPath(`/recipient/${id}/stats`));
|
|
},
|
|
|
|
/**
|
|
* Get a recipient by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/recipient/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Update a recipient.
|
|
*
|
|
* @param {object} recipient
|
|
* @param {string} recipient.id
|
|
* @param {string} recipient.email
|
|
* @param {string} recipient.phone
|
|
* @param {string} recipient.extraIdentifier
|
|
* @param {string} recipient.firstName
|
|
* @param {string} recipient.lastName
|
|
* @param {string} recipient.position
|
|
* @param {string} recipient.department
|
|
* @param {string} recipient.city
|
|
* @param {string} recipient.country
|
|
* @param {string} recipient.misc
|
|
* @param {string} recipient.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async ({
|
|
id,
|
|
email,
|
|
phone,
|
|
extraIdentifier,
|
|
firstName,
|
|
lastName,
|
|
position,
|
|
department,
|
|
city,
|
|
country,
|
|
misc,
|
|
companyID
|
|
}) => {
|
|
return await patchJSON(this.getPath(`/recipient/${id}`), {
|
|
email: email,
|
|
phone: phone,
|
|
extraIdentifier: extraIdentifier,
|
|
firstName: firstName,
|
|
lastName: lastName,
|
|
position: position,
|
|
department: department,
|
|
city: city,
|
|
country: country,
|
|
misc: misc,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Create a new recipient.
|
|
*
|
|
* @param {object} recipient
|
|
* @param {string} recipient.email
|
|
* @param {string} recipient.phone
|
|
* @param {string} recipient.extraIdentifier
|
|
* @param {string} recipient.firstName
|
|
* @param {string} recipient.lastName
|
|
* @param {string} recipient.position
|
|
* @param {string} recipient.department
|
|
* @param {string} recipient.city
|
|
* @param {string} recipient.country
|
|
* @param {string} recipient.misc
|
|
* @param {string} recipient.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({
|
|
email,
|
|
phone,
|
|
extraIdentifier,
|
|
firstName,
|
|
lastName,
|
|
position,
|
|
department,
|
|
city,
|
|
country,
|
|
misc,
|
|
companyID
|
|
}) => {
|
|
return await postJSON(this.getPath('/recipient/'), {
|
|
email: email,
|
|
phone: phone,
|
|
extraIdentifier: extraIdentifier,
|
|
firstName: firstName,
|
|
lastName: lastName,
|
|
position: position,
|
|
department: department,
|
|
city: city,
|
|
country: country,
|
|
misc: misc,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete a recipient.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/recipient/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Create a new recipient group.
|
|
*
|
|
* @param {string} name
|
|
* @param {string} companyID
|
|
* @param {Object[]} recipients // TODO define type for recipient
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
createGroup: async (name, companyID, recipients) => {
|
|
return await postJSON(this.getPath('/recipient/group'), {
|
|
name: name,
|
|
companyID: companyID,
|
|
recipients: recipients ?? []
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Create a dynamic recipient group.
|
|
*
|
|
* @param {string} name
|
|
* @param {string|null} companyID
|
|
* @param {string} filterField - recipient attribute to filter on (position, department, city, country, misc)
|
|
* @param {string} filterValue - value to match against the filter field
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
createDynamicGroup: async (name, companyID, filterField, filterValue) => {
|
|
return await postJSON(this.getPath('/recipient/group'), {
|
|
name: name,
|
|
companyID: companyID,
|
|
isDynamic: true,
|
|
filterField: filterField,
|
|
filterValue: filterValue
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Update a recipient group - not the recipients in the group.
|
|
*
|
|
* @param {object} group
|
|
* @param {string} group.id
|
|
* @param {string} [group.name ]
|
|
* @param {string} [group.companyID]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
updateGroup: async ({ id, name, companyID }) => {
|
|
return await patchJSON(this.getPath(`/recipient/group/${id}`), {
|
|
name: name,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Update a dynamic recipient group.
|
|
*
|
|
* @param {object} group
|
|
* @param {string} group.id
|
|
* @param {string} [group.name]
|
|
* @param {string} [group.filterField]
|
|
* @param {string} [group.filterValue]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
updateDynamicGroup: async ({ id, name, filterField, filterValue }) => {
|
|
return await patchJSON(this.getPath(`/recipient/group/${id}`), {
|
|
name: name,
|
|
isDynamic: true,
|
|
filterField: filterField,
|
|
filterValue: filterValue
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get all recipient groups using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllGroups: async (options, companyID) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/recipient/group?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all recipients in a group using pagination.
|
|
*
|
|
* @param {string} id
|
|
* @param {TableURLParams} options
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllByGroupID: async (id, options) => {
|
|
return await getJSON(
|
|
this.getPath(`/recipient/group/${id}/recipients?${appendQuery(options)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get a recipient group by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getGroupByID: async (id) => {
|
|
return await getJSON(this.getPath(`/recipient/group/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Import recipients.
|
|
*
|
|
* @param {Object} import
|
|
* @param {Object[]} import.recipients // TODO define type for recipients
|
|
* @param {string} import.companyID
|
|
* @param {boolean} import.ignoreOverwriteEmptyFields existing recipient data for empty fields
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
import: async ({ recipients, companyID, ignoreOverwriteEmptyFields = false }) => {
|
|
return await postJSON(this.getPath(`/recipient/import`), {
|
|
recipients: recipients,
|
|
ignoreOverwriteEmptyFields: ignoreOverwriteEmptyFields,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Import recipients to a group.
|
|
*
|
|
* @param {Object} import
|
|
* @param {Object[]} import.recipients // TODO define type for recipients
|
|
* @param {string} import.groupID
|
|
* @param {string} import.companyID
|
|
* @param {boolean} import.ignoreOverwriteEmptyFields existing recipient data for empty fields
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
importToGroup: async ({
|
|
recipients,
|
|
groupID,
|
|
companyID,
|
|
ignoreOverwriteEmptyFields = false
|
|
}) => {
|
|
return await putJSON(this.getPath(`/recipient/group/${groupID}/import`), {
|
|
recipients: recipients,
|
|
ignoreOverwriteEmptyFields: ignoreOverwriteEmptyFields,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {string} recipientID
|
|
* @returns
|
|
*/
|
|
export: async (recipientID) => {
|
|
window.open(this.getPath(`/recipient/${recipientID}/export`), '_blank');
|
|
},
|
|
|
|
/**
|
|
* Add recipients to a group.
|
|
*
|
|
* @param {string} groupID
|
|
* @param {Object[]} recipients // TODO define type for recipients
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
addToGroup: async (groupID, recipients) => {
|
|
return await postJSON(this.getPath(`/recipient/group/${groupID}/recipients`), {
|
|
recipientIDs: recipients
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Remove recipients from a group.
|
|
*
|
|
* @param {string} groupID
|
|
* @param {*[]} recipients // TODO define type for recipients
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
removeFromGroup: async (groupID, recipients) => {
|
|
return await deleteJSON(this.getPath(`/recipient/group/${groupID}/recipients`), {
|
|
recipientIDs: recipients
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete a recipient group.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
deleteGroup: async (id) => {
|
|
return await deleteJSON(this.getPath(`/recipient/group/${id}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* api sender is the API for the API sender related operations.
|
|
*
|
|
* @type {Object}
|
|
**/
|
|
apiSender = {
|
|
/**
|
|
* Create a new API sender.
|
|
*
|
|
* @param {Object} sender
|
|
* @param {string} sender.name
|
|
* @param {string} sender.apiKey
|
|
* @param {string} sender.companyID
|
|
* @param {string} sender.customField1
|
|
* @param {string} sender.customField2
|
|
* @param {string} sender.customField3
|
|
* @param {string} sender.customField4
|
|
* @param {string} sender.oauthProviderID
|
|
* @param {string} sender.requestMethod
|
|
* @param {string} sender.requestURL
|
|
* @param {APISenderHeader[]} sender.requestHeaders
|
|
* @param {string} sender.requestBody
|
|
* @param {string|number} sender.expectedResponseStatusCode
|
|
* @param {APISenderHeader[]} sender.expectedResponseHeaders
|
|
* @param {string} sender.expectedResponseBody
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({
|
|
name,
|
|
apiKey,
|
|
companyID,
|
|
customField1,
|
|
customField2,
|
|
customField3,
|
|
customField4,
|
|
oauthProviderID,
|
|
requestMethod,
|
|
requestURL,
|
|
requestHeaders,
|
|
requestBody,
|
|
expectedResponseStatusCode,
|
|
expectedResponseHeaders,
|
|
expectedResponseBody
|
|
}) => {
|
|
if (typeof expectedResponseStatusCode === 'string' && expectedResponseStatusCode.length > 0) {
|
|
expectedResponseStatusCode = parseInt(expectedResponseStatusCode);
|
|
} else {
|
|
expectedResponseStatusCode = null;
|
|
}
|
|
return await postJSON(this.getPath('/api-sender'), {
|
|
name: name,
|
|
apiKey: apiKey,
|
|
companyID: companyID,
|
|
customField1: customField1,
|
|
customField2: customField2,
|
|
customField3: customField3,
|
|
customField4: customField4,
|
|
oauthProviderID: oauthProviderID,
|
|
requestMethod: requestMethod,
|
|
requestURL: requestURL,
|
|
requestHeaders: requestHeaders,
|
|
requestBody: requestBody,
|
|
expectedResponseStatusCode: expectedResponseStatusCode,
|
|
expectedResponseHeaders: expectedResponseHeaders,
|
|
expectedResponseBody: expectedResponseBody
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Update an API sender.
|
|
*
|
|
* @param {Object} sender
|
|
* @param {string} sender.id
|
|
* @param {string} sender.name
|
|
* @param {string} sender.apiKey
|
|
* @param {string} sender.companyID
|
|
* @param {string} sender.customField1
|
|
* @param {string} sender.customField2
|
|
* @param {string} sender.customField3
|
|
* @param {string} sender.customField4
|
|
* @param {string} sender.oauthProviderID
|
|
* @param {string} sender.requestMethod
|
|
* @param {string} sender.requestURL
|
|
* @param {APISenderHeader[]} sender.requestHeaders
|
|
* @param {string} sender.requestBody
|
|
* @param {string|number} sender.expectedResponseStatusCode
|
|
* @param {APISenderHeader[]} sender.expectedResponseHeaders
|
|
* @param {string} sender.expectedResponseBody
|
|
*/
|
|
update: async ({
|
|
id,
|
|
name,
|
|
apiKey,
|
|
companyID,
|
|
customField1,
|
|
customField2,
|
|
customField3,
|
|
customField4,
|
|
oauthProviderID,
|
|
requestMethod,
|
|
requestURL,
|
|
requestHeaders,
|
|
requestBody,
|
|
expectedResponseStatusCode,
|
|
expectedResponseHeaders,
|
|
expectedResponseBody
|
|
}) => {
|
|
if (typeof expectedResponseStatusCode === 'string' && expectedResponseStatusCode.length > 0) {
|
|
expectedResponseStatusCode = parseInt(expectedResponseStatusCode);
|
|
} else if (typeof expectedResponseStatusCode === 'number') {
|
|
// noop
|
|
} else {
|
|
expectedResponseStatusCode = null;
|
|
}
|
|
|
|
return await patchJSON(this.getPath(`/api-sender/${id}`), {
|
|
name: name,
|
|
apiKey: apiKey,
|
|
companyID: companyID,
|
|
customField1: customField1,
|
|
customField2: customField2,
|
|
customField3: customField3,
|
|
customField4: customField4,
|
|
oauthProviderID: oauthProviderID,
|
|
requestMethod: requestMethod,
|
|
requestURL: requestURL,
|
|
requestHeaders: requestHeaders,
|
|
requestBody: requestBody,
|
|
expectedResponseStatusCode: expectedResponseStatusCode,
|
|
expectedResponseHeaders: expectedResponseHeaders,
|
|
expectedResponseBody: expectedResponseBody
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Get all API senders using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/api-sender?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all overview API senders using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllOverview: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/api-sender/overview?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get an API sender by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/api-sender/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Delete an API sender by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/api-sender/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Send a test request to an API sender.
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
test: async (id) => {
|
|
return await postJSON(this.getPath(`/api-sender/${id}/test`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* log is the API for log related operations.
|
|
*/
|
|
allowDeny = {
|
|
/**
|
|
* Create a new allowdeny list.
|
|
*
|
|
* @param {Object} allowdeny
|
|
* @param {string} allowdeny.name
|
|
* @param {string} allowdeny.cidrs
|
|
* @param {string} allowdeny.ja4Fingerprints
|
|
* @param {string} allowdeny.countryCodes
|
|
* @param {string} allowdeny.headers
|
|
* @param {boolean} allowdeny.allowed
|
|
* @param {string} allowdeny.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({ name, cidrs, ja4Fingerprints, countryCodes, headers, allowed, companyID }) => {
|
|
return await postJSON(this.getPath('/allow-deny'), {
|
|
name: name,
|
|
cidrs: cidrs,
|
|
ja4Fingerprints: ja4Fingerprints,
|
|
countryCodes: countryCodes,
|
|
headers: headers,
|
|
allowed: allowed,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* GetAll allowdeny list.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/allow-deny?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* GetAllOverview gets allowdeny list without cidrs.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllOverview: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(
|
|
`/allow-deny/overview?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`
|
|
)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get an allowdeny list by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/allow-deny/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Update an allowdeny list.
|
|
*
|
|
* @param {Object} allowdeny
|
|
* @param {string} allowdeny.id
|
|
* @param {string} allowdeny.name
|
|
* @param {string} allowdeny.cidrs
|
|
* @param {string} allowdeny.ja4Fingerprints
|
|
* @param {string} allowdeny.countryCodes
|
|
* @param {string} allowdeny.headers
|
|
* @param {string} allowdeny.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async ({ id, name, cidrs, ja4Fingerprints, countryCodes, headers, companyID }) => {
|
|
return await patchJSON(this.getPath(`/allow-deny/${id}`), {
|
|
name: name,
|
|
cidrs: cidrs,
|
|
ja4Fingerprints: ja4Fingerprints,
|
|
countryCodes: countryCodes,
|
|
headers: headers,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete an allowdeny list by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/allow-deny/${id}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* geoip is the API for GeoIP related operations.
|
|
*/
|
|
geoip = {
|
|
/**
|
|
* Get GeoIP metadata including available country codes.
|
|
*
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getMetadata: async () => {
|
|
return await getJSON(this.getPath('/geoip/metadata'));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* webhook is the API for web hook related operations.
|
|
*/
|
|
webhook = {
|
|
/**
|
|
* Create a new webhook.
|
|
*
|
|
* @param {Object} webhook
|
|
* @param {string} webhook.name
|
|
* @param {string} webhook.url
|
|
* @param {string} [webhook.secret]
|
|
* @param {string} [webhook.companyID]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({ name, url, secret, companyID }) => {
|
|
return await postJSON(this.getPath('/webhook'), {
|
|
name: name,
|
|
url: url,
|
|
secret: secret,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* GetAll webhooks.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/webhook?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get a webhook by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/webhook/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Update a webhook.
|
|
*
|
|
* @param {Object} webhook
|
|
* @param {string} webhook.id
|
|
* @param {string} webhook.name
|
|
* @param {string} webhook.url
|
|
* @param {string} webhook.secret
|
|
* @param {string} webhook.companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async ({ id, name, url, secret, companyID }) => {
|
|
return await patchJSON(this.getPath(`/webhook/${id}`), {
|
|
name: name,
|
|
url: url,
|
|
secret: secret,
|
|
companyID: companyID
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete a webhook by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/webhook/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Test a webhook.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
test: async (id) => {
|
|
return await postJSON(this.getPath(`/webhook/${id}/test`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* identifier is for campaign identifiers, ala. 'rid' in gophish
|
|
*/
|
|
identifier = {
|
|
/**
|
|
* @param {TableURLParams} options
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options) => {
|
|
return await getJSON(this.getPath(`/identifier?${appendQuery(options)}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* sso is for handling sso configuration
|
|
*/
|
|
sso = {
|
|
/**
|
|
* @param {object} sso
|
|
* @param {string} sso.clientID
|
|
* @param {string} sso.tenantID
|
|
* @param {string} sso.clientSecret
|
|
* @param {string} sso.redirectURL
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
upsert: async (sso) => {
|
|
return await postJSON(this.getPath(`/sso/entra-id`), sso);
|
|
},
|
|
|
|
isEnabled: async () => {
|
|
return await getJSON(this.getPath(`/sso/entra-id/enabled`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* utils is for useful utils
|
|
*/
|
|
utils = {
|
|
/**
|
|
* @param {object} qr
|
|
* @param {string} qr.url
|
|
* @param {number} qr.dotSize
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
qr: async (qr) => {
|
|
return await postJSON(this.getPath(`/qr/html`), qr);
|
|
}
|
|
};
|
|
|
|
version = {
|
|
/**
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
get: async () => {
|
|
return await getJSON(this.getPath(`/version`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* proxy is the API for Proxy related operations.
|
|
*/
|
|
proxy = {
|
|
/**
|
|
* Get a Proxy by its ID.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getByID: async (id) => {
|
|
return await getJSON(this.getPath(`/proxy/${id}`));
|
|
},
|
|
|
|
/**
|
|
* Get all Proxies using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAll: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/proxy?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Get all Proxies overview using pagination.
|
|
*
|
|
* @param {TableURLParams} options
|
|
* @param {string|null} companyID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getAllSubset: async (options, companyID = null) => {
|
|
return await getJSON(
|
|
this.getPath(`/proxy/overview?${appendQuery(options)}${this.appendCompanyQuery(companyID)}`)
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Create a new Proxy.
|
|
*
|
|
* @param {object} proxy
|
|
* @param {string} proxy.name
|
|
* @param {string} proxy.description
|
|
* @param {string} proxy.startURL
|
|
* @param {string} proxy.proxyConfig
|
|
* @param {string} proxy.companyID
|
|
* @param {string} [proxy.globalTLSKey]
|
|
* @param {string} [proxy.globalTLSPem]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
create: async ({
|
|
name,
|
|
description,
|
|
startURL,
|
|
proxyConfig,
|
|
companyID,
|
|
globalTLSKey,
|
|
globalTLSPem
|
|
}) => {
|
|
return await postJSON(this.getPath('/proxy'), {
|
|
name: name,
|
|
description: description,
|
|
startURL: startURL,
|
|
proxyConfig: proxyConfig,
|
|
companyID: companyID,
|
|
...(globalTLSKey ? { globalTLSKey } : {}),
|
|
...(globalTLSPem ? { globalTLSPem } : {})
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Update a Proxy.
|
|
*
|
|
* @param {string} id
|
|
* @param {object} proxy
|
|
* @param {string} proxy.name
|
|
* @param {string} proxy.description
|
|
* @param {string} proxy.startURL
|
|
* @param {string} proxy.proxyConfig
|
|
* @param {string} [proxy.globalTLSKey]
|
|
* @param {string} [proxy.globalTLSPem]
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
update: async (id, proxy) => {
|
|
return await patchJSON(this.getPath(`/proxy/${id}`), proxy);
|
|
},
|
|
|
|
/**
|
|
* Delete a Proxy.
|
|
*
|
|
* @param {string} id
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
delete: async (id) => {
|
|
return await deleteJSON(this.getPath(`/proxy/${id}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ipAllowList is the API for IP Allow List related operations.
|
|
*/
|
|
ipAllowList = {
|
|
/**
|
|
* Get IP allow list entries for a specific proxy configuration.
|
|
*
|
|
* @param {string} proxyConfigID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
getForProxyConfig: async (proxyConfigID) => {
|
|
return await getJSON(this.getPath(`/ip-allow-list/proxy-config/${proxyConfigID}`));
|
|
},
|
|
|
|
/**
|
|
* Clear all entries for a specific proxy configuration.
|
|
*
|
|
* @param {string} proxyConfigID
|
|
* @returns {Promise<ApiResponse>}
|
|
*/
|
|
clearForProxyConfig: async (proxyConfigID) => {
|
|
return await deleteJSON(this.getPath(`/ip-allow-list/clear-proxy-config/${proxyConfigID}`));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* import is for importing assets, landing pages and etc
|
|
*/
|
|
import = {
|
|
import: async (fileOrFormData) => {
|
|
if (fileOrFormData instanceof FormData) {
|
|
return await postMultipart(this.getPath('/import'), fileOrFormData);
|
|
} else if (fileOrFormData) {
|
|
const formData = new FormData();
|
|
formData.append('file', fileOrFormData);
|
|
return await postMultipart(this.getPath('/import'), formData);
|
|
}
|
|
}
|
|
};
|
|
}
|