Merge pull request #572 from ylei-tsubame/issues/419api-add-mail-config

Web UI: add API support for mail config functions
main
Digimer 11 months ago committed by GitHub
commit 1b923be6a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      striker-ui-api/src/lib/consts/SERVER_PATHS.ts
  2. 106
      striker-ui-api/src/lib/execManageAlerts.ts
  3. 35
      striker-ui-api/src/lib/request_handlers/alert-override/createAlertOverride.ts
  4. 23
      striker-ui-api/src/lib/request_handlers/alert-override/deleteAlertOverride.ts
  5. 91
      striker-ui-api/src/lib/request_handlers/alert-override/getAlertOverride.ts
  6. 83
      striker-ui-api/src/lib/request_handlers/alert-override/getAlertOverrideDetail.ts
  7. 45
      striker-ui-api/src/lib/request_handlers/alert-override/getAlertOverrideRequestBody.ts
  8. 5
      striker-ui-api/src/lib/request_handlers/alert-override/index.ts
  9. 38
      striker-ui-api/src/lib/request_handlers/alert-override/updateAlertOverride.ts
  10. 41
      striker-ui-api/src/lib/request_handlers/mail-recipient/createMailRecipient.ts
  11. 43
      striker-ui-api/src/lib/request_handlers/mail-recipient/deleteMailRecipient.ts
  12. 34
      striker-ui-api/src/lib/request_handlers/mail-recipient/getMailRecipient.ts
  13. 53
      striker-ui-api/src/lib/request_handlers/mail-recipient/getMailRecipientDetail.ts
  14. 49
      striker-ui-api/src/lib/request_handlers/mail-recipient/getMailRecipientRequestBody.ts
  15. 5
      striker-ui-api/src/lib/request_handlers/mail-recipient/index.ts
  16. 38
      striker-ui-api/src/lib/request_handlers/mail-recipient/updateMailRecipient.ts
  17. 35
      striker-ui-api/src/lib/request_handlers/mail-server/createMailServer.ts
  18. 23
      striker-ui-api/src/lib/request_handlers/mail-server/deleteMailServer.ts
  19. 39
      striker-ui-api/src/lib/request_handlers/mail-server/getMailServer.ts
  20. 68
      striker-ui-api/src/lib/request_handlers/mail-server/getMailServerDetail.ts
  21. 63
      striker-ui-api/src/lib/request_handlers/mail-server/getMailServerRequestBody.ts
  22. 5
      striker-ui-api/src/lib/request_handlers/mail-server/index.ts
  23. 38
      striker-ui-api/src/lib/request_handlers/mail-server/updateMailServer.ts
  24. 20
      striker-ui-api/src/routes/alert-override.ts
  25. 6
      striker-ui-api/src/routes/index.ts
  26. 20
      striker-ui-api/src/routes/mail-recipient.ts
  27. 20
      striker-ui-api/src/routes/mail-server.ts
  28. 26
      striker-ui-api/src/types/ApiAlertOverride.d.ts
  29. 22
      striker-ui-api/src/types/ApiMailRecipient.d.ts
  30. 23
      striker-ui-api/src/types/ApiMailServer.d.ts

@ -34,6 +34,7 @@ const EMPTY_SERVER_PATHS: ServerPath = {
'anvil-delete-server': {}, 'anvil-delete-server': {},
'anvil-get-server-screenshot': {}, 'anvil-get-server-screenshot': {},
'anvil-join-anvil': {}, 'anvil-join-anvil': {},
'anvil-manage-alerts': {},
'anvil-manage-keys': {}, 'anvil-manage-keys': {},
'anvil-manage-power': {}, 'anvil-manage-power': {},
'anvil-provision-server': {}, 'anvil-provision-server': {},

@ -0,0 +1,106 @@
import assert from 'assert';
import { SpawnSyncReturns, spawnSync } from 'child_process';
import { P_UUID, SERVER_PATHS } from './consts';
import { stdoutVar } from './shell';
const MAP_TO_FLAG_BUNDLE: {
'alert-overrides': Record<keyof AlertOverrideRequestBody | 'uuid', string>;
'mail-servers': Record<keyof MailServerRequestBody | 'uuid', string>;
recipients: Record<keyof MailRecipientRequestBody | 'uuid', string>;
} = {
'alert-overrides': {
hostUuid: '--alert-override-host-uuid',
level: '--alert-override-alert-level',
mailRecipientUuid: '--alert-override-recipient-uuid',
uuid: '--alert-override-uuid',
},
'mail-servers': {
address: '--mail-server-address',
authentication: '--mail-server-authentication',
heloDomain: '--mail-server-helo-domain',
password: '--mail-server-password',
port: '--mail-server-port',
security: '--mail-server-security',
username: '--mail-server-username',
uuid: '--mail-server-uuid',
},
recipients: {
email: '--recipient-email',
language: '--recipient-language',
level: '--recipient-level',
name: '--recipient-name',
uuid: '--recipient-uuid',
},
};
export const execManageAlerts = (
entities: 'alert-overrides' | 'mail-servers' | 'recipients',
operation: 'add' | 'edit' | 'delete',
{
body,
uuid,
}: {
body?: Record<string, unknown>;
uuid?: string;
} = {},
): { uuid?: string } => {
const shallow = { ...body };
if (uuid) {
shallow.uuid = uuid;
}
const commandArgs: string[] = Object.entries(
MAP_TO_FLAG_BUNDLE[entities],
).reduce(
(previous, [key, flag]) => {
const value = shallow[key];
if (value !== undefined) {
previous.push(flag, String(value));
}
return previous;
},
[`--${entities}`, `--${operation}`, '--yes'],
);
stdoutVar({ commandArgs }, 'Manage alerts with args: ');
let result: SpawnSyncReturns<string>;
try {
result = spawnSync(
SERVER_PATHS.usr.sbin['anvil-manage-alerts'].self,
commandArgs,
{ encoding: 'utf-8', timeout: 10000 },
);
const { error, signal, status, stderr, stdout } = result;
stdoutVar(
{ error, signal, status, stderr, stdout },
'Manage alerts returned: ',
);
assert.strictEqual(
status,
0,
`Expected status to be 0, but got [${status}]`,
);
assert.strictEqual(
error,
undefined,
`Expected no error, but got [${error}]`,
);
} catch (error) {
throw new Error(`Failed to complete manage alerts; CAUSE: ${error}`);
}
return {
uuid: result.stdout.match(new RegExp(P_UUID))?.[0],
};
};

@ -0,0 +1,35 @@
import { RequestHandler } from 'express';
import { execManageAlerts } from '../../execManageAlerts';
import { getAlertOverrideRequestBody } from './getAlertOverrideRequestBody';
import { stderr, stdout } from '../../shell';
export const createAlertOverride: RequestHandler<
undefined,
undefined,
AlertOverrideRequestBody
> = (request, response) => {
const { body: rBody = {} } = request;
stdout(`Begin creating alert override.`);
let body: AlertOverrideRequestBody;
try {
body = getAlertOverrideRequestBody(rBody);
} catch (error) {
stderr(`Failed to process alert override input; CAUSE: ${error}`);
return response.status(400).send();
}
try {
execManageAlerts('alert-overrides', 'add', { body });
} catch (error) {
stderr(`Failed to create alert override; CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(201).send();
};

@ -0,0 +1,23 @@
import { RequestHandler } from 'express';
import { execManageAlerts } from '../../execManageAlerts';
import { stderr } from '../../shell';
export const deleteAlertOverride: RequestHandler<AlertOverrideReqParams> = (
request,
response,
) => {
const {
params: { uuid },
} = request;
try {
execManageAlerts('alert-overrides', 'delete', { uuid });
} catch (error) {
stderr(`Failed to delete alert override: CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(204).send();
};

@ -0,0 +1,91 @@
import { RequestHandler } from 'express';
import { DELETED } from '../../consts';
import { buildUnknownIDCondition } from '../../buildCondition';
import buildGetRequestHandler from '../buildGetRequestHandler';
import { buildQueryResultReducer } from '../../buildQueryResultModifier';
import { getShortHostName } from '../../disassembleHostName';
export const getAlertOverride: RequestHandler<
AlertOverrideReqParams,
undefined,
undefined,
AlertOverrideReqQuery
> = buildGetRequestHandler((request, options) => {
const {
query: { 'mail-recipient': mailRecipient },
} = request;
const { after: mailRecipientCond } = buildUnknownIDCondition(
mailRecipient,
'b.recipient_uuid',
{ onFallback: () => 'TRUE' },
);
const query = `
SELECT
a.alert_override_uuid,
a.alert_override_alert_level,
b.recipient_uuid,
b.recipient_name,
c.host_uuid,
c.host_name,
d.anvil_uuid,
d.anvil_name
FROM alert_overrides AS a
JOIN recipients AS b
ON a.alert_override_recipient_uuid = b.recipient_uuid
JOIN hosts AS c
ON a.alert_override_host_uuid = c.host_uuid
JOIN anvils AS d
ON c.host_uuid IN (d.anvil_node1_host_uuid, d.anvil_node2_host_uuid)
WHERE a.alert_override_alert_level != -1
AND b.recipient_name != '${DELETED}'
AND ${mailRecipientCond}
ORDER BY b.recipient_name ASC;`;
const afterQueryReturn: QueryResultModifierFunction =
buildQueryResultReducer<AlertOverrideOverviewList>(
(
previous,
[
uuid,
level,
mailRecipientUuid,
mailRecipientName,
hostUuid,
hostName,
anvilUuid,
anvilName,
],
) => {
previous[uuid] = {
level: Number(level),
mailRecipient: {
name: mailRecipientName,
uuid: mailRecipientUuid,
},
node: {
name: anvilName,
uuid: anvilUuid,
},
subnode: {
name: hostName,
short: getShortHostName(hostName),
uuid: hostUuid,
},
uuid,
};
return previous;
},
{},
);
if (options) {
options.afterQueryReturn = afterQueryReturn;
}
return query;
});

@ -0,0 +1,83 @@
import { RequestHandler } from 'express';
import { DELETED } from '../../consts';
import buildGetRequestHandler from '../buildGetRequestHandler';
import { buildQueryResultModifier } from '../../buildQueryResultModifier';
import { getShortHostName } from '../../disassembleHostName';
import { sanitize } from '../../sanitize';
export const getAlertOverrideDetail: RequestHandler<AlertOverrideReqParams> =
buildGetRequestHandler((request, options) => {
const {
params: { uuid: rUuid },
} = request;
const uuid = sanitize(rUuid, 'string', { modifierType: 'sql' });
const query = `
SELECT
a.alert_override_uuid,
a.alert_override_alert_level,
b.recipient_uuid,
b.recipient_name,
c.host_uuid,
c.host_name,
d.anvil_uuid,
d.anvil_name
FROM alert_overrides AS a
JOIN recipients AS b
ON a.alert_override_recipient_uuid = b.recipient_uuid
JOIN hosts AS c
ON a.alert_override_host_uuid = c.host_uuid
JOIN anvils AS d
ON c.host_uuid IN (d.anvil_node1_host_uuid, d.anvil_node2_host_uuid)
WHERE a.alert_override_alert_level != -1
AND b.recipient_name != '${DELETED}'
AND a.alert_override_uuid = '${uuid}'
ORDER BY b.recipient_name ASC;`;
const afterQueryReturn: QueryResultModifierFunction =
buildQueryResultModifier<AlertOverrideDetail | undefined>((rows) => {
if (!rows.length) {
return undefined;
}
const {
0: [
uuid,
level,
mailRecipientUuid,
mailRecipientName,
hostUuid,
hostName,
anvilUuid,
anvilName,
],
} = rows;
return {
level: Number(level),
mailRecipient: {
name: mailRecipientName,
uuid: mailRecipientUuid,
},
node: {
name: anvilName,
uuid: anvilUuid,
},
subnode: {
name: hostName,
short: getShortHostName(hostName),
uuid: hostUuid,
},
uuid,
};
});
if (options) {
options.afterQueryReturn = afterQueryReturn;
}
return query;
});

@ -0,0 +1,45 @@
import assert from 'assert';
import { REP_UUID } from '../../consts';
import { sanitize } from '../../sanitize';
export const getAlertOverrideRequestBody = (
body: Partial<AlertOverrideRequestBody>,
uuid?: string,
): AlertOverrideRequestBody => {
const {
hostUuid: rHostUuid,
level: rLevel,
mailRecipientUuid: rMailRecipientUuid,
} = body;
const hostUuid = sanitize(rHostUuid, 'string');
const level = sanitize(rLevel, 'number');
const mailRecipientUuid = sanitize(rMailRecipientUuid, 'string');
if (uuid) {
assert(REP_UUID.test(uuid), `Expected valid UUIDv4; got [${uuid}]`);
}
assert(
REP_UUID.test(hostUuid),
`Expected valid host UUIDv4; got [${hostUuid}]`,
);
assert(
Number.isSafeInteger(level),
`Expected level to be an integer; got [${level}]`,
);
assert(
REP_UUID.test(mailRecipientUuid),
`Expected valid mail recipient UUIDv4; got [${mailRecipientUuid}]`,
);
return {
hostUuid,
level,
mailRecipientUuid,
};
};

@ -0,0 +1,5 @@
export * from './createAlertOverride';
export * from './deleteAlertOverride';
export * from './getAlertOverride';
export * from './getAlertOverrideDetail';
export * from './updateAlertOverride';

@ -0,0 +1,38 @@
import { RequestHandler } from 'express';
import { execManageAlerts } from '../../execManageAlerts';
import { getAlertOverrideRequestBody } from './getAlertOverrideRequestBody';
import { stderr, stdout } from '../../shell';
export const updateAlertOverride: RequestHandler<
AlertOverrideReqParams,
undefined,
AlertOverrideRequestBody
> = (request, response) => {
const {
body: rBody = {},
params: { uuid },
} = request;
stdout('Begin updating alert override.');
let body: AlertOverrideRequestBody;
try {
body = getAlertOverrideRequestBody(rBody, uuid);
} catch (error) {
stderr(`Failed to process alert override input; CAUSE: ${error}`);
return response.status(400).send();
}
try {
execManageAlerts('alert-overrides', 'edit', { body, uuid });
} catch (error) {
stderr(`Failed to update alert override; CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(200).send();
};

@ -0,0 +1,41 @@
import { RequestHandler } from 'express';
import { execManageAlerts } from '../../execManageAlerts';
import { getMailRecipientRequestBody } from './getMailRecipientRequestBody';
import { stderr, stdout } from '../../shell';
export const createMailRecipient: RequestHandler<
undefined,
MailRecipientResponseBody | undefined,
MailRecipientRequestBody
> = (request, response) => {
const { body: rBody = {} } = request;
stdout('Begin creating mail recipient.');
let reqBody: MailRecipientRequestBody;
try {
reqBody = getMailRecipientRequestBody(rBody);
} catch (error) {
stderr(`Failed to process mail recipient input; CAUSE: ${error}`);
return response.status(400).send();
}
let resBody: MailRecipientResponseBody | undefined;
try {
const { uuid = '' } = execManageAlerts('recipients', 'add', {
body: reqBody,
});
resBody = { uuid };
} catch (error) {
stderr(`Failed to create mail recipient; CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(201).send(resBody);
};

@ -0,0 +1,43 @@
import { RequestHandler } from 'express';
import { query } from '../../accessModule';
import { execManageAlerts } from '../../execManageAlerts';
import { sanitize } from '../../sanitize';
import { stderr } from '../../shell';
export const deleteMailRecipient: RequestHandler<
MailRecipientParamsDictionary
> = async (request, response) => {
const {
params: { uuid: rUuid },
} = request;
const uuid = sanitize(rUuid, 'string', { modifierType: 'sql' });
try {
const rows = await query<[string][]>(
`SELECT alert_override_uuid
FROM alert_overrides
WHERE alert_override_alert_level != -1
AND alert_override_recipient_uuid = '${uuid}';`,
);
rows.forEach(([u]) =>
execManageAlerts('alert-overrides', 'delete', { uuid: u }),
);
} catch (error) {
stderr(`Failed to delete related alert override records; CAUSE ${error}`);
return response.status(500).send();
}
try {
execManageAlerts('recipients', 'delete', { uuid });
} catch (error) {
stderr(`Failed to delete alert recipient; CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(204).send();
};

@ -0,0 +1,34 @@
import { RequestHandler } from 'express';
import { DELETED } from '../../consts';
import buildGetRequestHandler from '../buildGetRequestHandler';
import { buildQueryResultReducer } from '../../buildQueryResultModifier';
export const getMailRecipient: RequestHandler = buildGetRequestHandler(
(request, options) => {
const query = `
SELECT
a.recipient_uuid,
a.recipient_name
FROM recipients AS a
WHERE a.recipient_name != '${DELETED}'
ORDER BY a.recipient_name ASC;`;
const afterQueryReturn: QueryResultModifierFunction =
buildQueryResultReducer<MailRecipientOverviewList>(
(previous, [uuid, name]) => {
previous[uuid] = { name, uuid };
return previous;
},
{},
);
if (options) {
options.afterQueryReturn = afterQueryReturn;
}
return query;
},
);

@ -0,0 +1,53 @@
import { RequestHandler } from 'express';
import { DELETED } from '../../consts';
import buildGetRequestHandler from '../buildGetRequestHandler';
import { buildQueryResultModifier } from '../../buildQueryResultModifier';
import { sanitize } from '../../sanitize';
export const getMailRecipientDetail: RequestHandler<MailRecipientParamsDictionary> =
buildGetRequestHandler((request, options) => {
const {
params: { uuid: rUuid },
} = request;
const uuid = sanitize(rUuid, 'string', { modifierType: 'sql' });
const query = `
SELECT
a.recipient_uuid,
a.recipient_name,
a.recipient_email,
a.recipient_language,
a.recipient_level
FROM recipients AS a
WHERE a.recipient_name != '${DELETED}'
AND a.recipient_uuid = '${uuid}'
ORDER BY a.recipient_name ASC;`;
const afterQueryReturn: QueryResultModifierFunction =
buildQueryResultModifier<MailRecipientDetail | undefined>((rows) => {
if (!rows.length) {
return undefined;
}
const {
0: [uuid, name, email, language, level],
} = rows;
return {
email,
language,
level: Number(level),
name,
uuid,
};
});
if (options) {
options.afterQueryReturn = afterQueryReturn;
}
return query;
});

@ -0,0 +1,49 @@
import assert from 'assert';
import { REP_UUID } from '../../consts';
import { sanitize } from '../../sanitize';
export const getMailRecipientRequestBody = (
body: Partial<MailRecipientRequestBody>,
uuid?: string,
): MailRecipientRequestBody => {
const {
email: rEmail,
language: rLanguage,
level: rLevel,
name: rName,
} = body;
const email = sanitize(rEmail, 'string');
const language = sanitize(rLanguage, 'string', { fallback: 'en_CA' });
const level = sanitize(rLevel, 'number');
const name = sanitize(rName, 'string');
if (uuid) {
assert(REP_UUID.test(uuid), `Expected valid UUIDv4; got [${uuid}]`);
}
assert.ok(email.length, `Expected email; got [${email}]`);
if (language) {
assert.ok(
language.length,
`Expected valid language code; got [${language}]`,
);
}
assert(
Number.isSafeInteger(level),
`Expected level to be an integer; got [${level}]`,
);
assert.ok(name.length, `Expected name; got [${name}]`);
return {
email,
language,
level,
name,
};
};

@ -0,0 +1,5 @@
export * from './createMailRecipient';
export * from './deleteMailRecipient';
export * from './getMailRecipient';
export * from './getMailRecipientDetail';
export * from './updateMailRecipient';

@ -0,0 +1,38 @@
import { RequestHandler } from 'express';
import { execManageAlerts } from '../../execManageAlerts';
import { getMailRecipientRequestBody } from './getMailRecipientRequestBody';
import { stderr, stdout } from '../../shell';
export const updateMailRecipient: RequestHandler<
MailRecipientParamsDictionary,
undefined,
MailRecipientRequestBody
> = (request, response) => {
const {
body: rBody = {},
params: { uuid },
} = request;
stdout('Begin updating mail recipient.');
let body: MailRecipientRequestBody;
try {
body = getMailRecipientRequestBody(rBody, uuid);
} catch (error) {
stderr(`Failed to process mail recipient input; CAUSE: ${error}`);
return response.status(400).send();
}
try {
execManageAlerts('recipients', 'edit', { body, uuid });
} catch (error) {
stderr(`Failed to update mail recipient; CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(200).send();
};

@ -0,0 +1,35 @@
import { RequestHandler } from 'express';
import { execManageAlerts } from '../../execManageAlerts';
import { getMailServerRequestBody } from './getMailServerRequestBody';
import { stderr, stdout } from '../../shell';
export const createMailServer: RequestHandler<
undefined,
undefined,
MailServerRequestBody
> = (request, response) => {
const { body: rBody = {} } = request;
stdout('Begin creating mail server.');
let body: MailServerRequestBody;
try {
body = getMailServerRequestBody(rBody);
} catch (error) {
stderr(`Failed to process mail server input; CAUSE: ${error}`);
return response.status(400).send();
}
try {
execManageAlerts('mail-servers', 'add', { body });
} catch (error) {
stderr(`Failed to create mail server; CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(201).send();
};

@ -0,0 +1,23 @@
import { RequestHandler } from 'express';
import { execManageAlerts } from '../../execManageAlerts';
import { stderr } from '../../shell';
export const deleteMailServer: RequestHandler<MailServerParamsDictionary> = (
request,
response,
) => {
const {
params: { uuid },
} = request;
try {
execManageAlerts('mail-servers', 'delete', { uuid });
} catch (error) {
stderr(`Failed to delete mail server; CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(204).send();
};

@ -0,0 +1,39 @@
import { RequestHandler } from 'express';
import { DELETED } from '../../consts';
import buildGetRequestHandler from '../buildGetRequestHandler';
import { buildQueryResultReducer } from '../../buildQueryResultModifier';
export const getMailServer: RequestHandler = buildGetRequestHandler(
(request, options) => {
const query = `
SELECT
a.mail_server_uuid,
a.mail_server_address,
a.mail_server_port
FROM mail_servers AS a
WHERE a.mail_server_helo_domain != '${DELETED}'
ORDER BY a.mail_server_address;`;
const afterQueryReturn: QueryResultModifierFunction =
buildQueryResultReducer<MailServerOverviewList>(
(previous, [uuid, address, port]) => {
previous[uuid] = {
address,
port: Number(port),
uuid,
};
return previous;
},
{},
);
if (options) {
options.afterQueryReturn = afterQueryReturn;
}
return query;
},
);

@ -0,0 +1,68 @@
import { RequestHandler } from 'express';
import { DELETED } from '../../consts';
import buildGetRequestHandler from '../buildGetRequestHandler';
import { buildQueryResultModifier } from '../../buildQueryResultModifier';
import { sanitize } from '../../sanitize';
export const getMailServerDetail: RequestHandler<MailServerParamsDictionary> =
buildGetRequestHandler((request, options) => {
const {
params: { uuid: rUuid },
} = request;
const uuid = sanitize(rUuid, 'string', { modifierType: 'sql' });
const query = `
SELECT
a.mail_server_uuid,
a.mail_server_address,
a.mail_server_port,
a.mail_server_username,
a.mail_server_password,
a.mail_server_security,
a.mail_server_authentication,
a.mail_server_helo_domain
FROM mail_servers AS a
WHERE a.mail_server_helo_domain != '${DELETED}'
AND a.mail_server_uuid = '${uuid}'
ORDER BY a.mail_server_address ASC;`;
const afterQueryReturn: QueryResultModifierFunction =
buildQueryResultModifier<MailServerDetail | undefined>((rows) => {
if (!rows.length) {
return undefined;
}
const {
0: [
uuid,
address,
port,
username,
password,
security,
authentication,
heloDomain,
],
} = rows;
return {
address,
authentication,
heloDomain,
password,
port: Number(port),
security,
username,
uuid,
};
});
if (options) {
options.afterQueryReturn = afterQueryReturn;
}
return query;
});

@ -0,0 +1,63 @@
import assert from 'assert';
import { REP_UUID } from '../../consts';
import { sanitize } from '../../sanitize';
export const getMailServerRequestBody = (
body: Partial<MailServerRequestBody>,
uuid?: string,
): MailServerRequestBody => {
const {
address: rAddress,
authentication: rAuthentication,
heloDomain: rHeloDomain,
password: rPassword,
port: rPort,
security: rSecurity,
username: rUsername,
} = body;
const address = sanitize(rAddress, 'string');
const authentication = sanitize(rAuthentication, 'string', {
fallback: 'none',
});
const heloDomain = sanitize(rHeloDomain, 'string');
const password = sanitize(rPassword, 'string');
const port = sanitize(rPort, 'number', { fallback: 587 });
const security = sanitize(rSecurity, 'string', { fallback: 'none' });
const username = sanitize(rUsername, 'string');
if (uuid) {
assert(REP_UUID.test(uuid), `Expected valid UUIDv4; got [${uuid}]`);
}
assert.ok(address.length, `Expected address; got [${address}]`);
assert(
['none', 'plain-text', 'encrypted'].includes(authentication),
`Expected authentication to be 'none', 'plain-text', or 'encrypted'; got [${authentication}]`,
);
assert.ok(heloDomain.length, `Expected HELO domain; got [${heloDomain}]`);
assert(
Number.isSafeInteger(port),
`Expected port to be an integer; got [${port}]`,
);
assert(
['none', 'starttls', 'tls-ssl'].includes(security),
`Expected security to be 'none', 'starttls', or 'tls-ssl'; got [${security}]`,
);
return {
address,
authentication,
heloDomain,
password,
port,
security,
username,
};
};

@ -0,0 +1,5 @@
export * from './createMailServer';
export * from './deleteMailServer';
export * from './getMailServer';
export * from './getMailServerDetail';
export * from './updateMailServer';

@ -0,0 +1,38 @@
import { RequestHandler } from 'express';
import { execManageAlerts } from '../../execManageAlerts';
import { getMailServerRequestBody } from './getMailServerRequestBody';
import { stderr, stdout } from '../../shell';
export const updateMailServer: RequestHandler<
MailServerParamsDictionary,
undefined,
MailServerRequestBody
> = (request, response) => {
const {
body: rBody = {},
params: { uuid },
} = request;
stdout('Begin updating mail server.');
let body: MailServerRequestBody;
try {
body = getMailServerRequestBody(rBody, uuid);
} catch (error) {
stderr(`Failed to process mail server input; CAUSE: ${error}`);
return response.status(400).send();
}
try {
execManageAlerts('mail-servers', 'edit', { body, uuid });
} catch (error) {
stderr(`Failed to update mail server; CAUSE: ${error}`);
return response.status(500).send();
}
return response.status(200).send();
};

@ -0,0 +1,20 @@
import express from 'express';
import {
createAlertOverride,
deleteAlertOverride,
getAlertOverride,
getAlertOverrideDetail,
updateAlertOverride,
} from '../lib/request_handlers/alert-override';
const router = express.Router();
router
.delete('/:uuid', deleteAlertOverride)
.get('/', getAlertOverride)
.get('/:uuid', getAlertOverrideDetail)
.post('/', createAlertOverride)
.put('/:uuid', updateAlertOverride);
export default router;

@ -1,3 +1,4 @@
import alertOverrideRouter from './alert-override';
import anvilRouter from './anvil'; import anvilRouter from './anvil';
import authRouter from './auth'; import authRouter from './auth';
import commandRouter from './command'; import commandRouter from './command';
@ -7,6 +8,8 @@ import fileRouter from './file';
import hostRouter from './host'; import hostRouter from './host';
import initRouter from './init'; import initRouter from './init';
import jobRouter from './job'; import jobRouter from './job';
import mailRecipientRouter from './mail-recipient';
import mailServerRouter from './mail-server';
import manifestRouter from './manifest'; import manifestRouter from './manifest';
import networkInterfaceRouter from './network-interface'; import networkInterfaceRouter from './network-interface';
import serverRouter from './server'; import serverRouter from './server';
@ -17,12 +20,15 @@ import userRouter from './user';
const routes = { const routes = {
private: { private: {
'alert-override': alertOverrideRouter,
anvil: anvilRouter, anvil: anvilRouter,
command: commandRouter, command: commandRouter,
fence: fenceRouter, fence: fenceRouter,
file: fileRouter, file: fileRouter,
host: hostRouter, host: hostRouter,
job: jobRouter, job: jobRouter,
'mail-recipient': mailRecipientRouter,
'mail-server': mailServerRouter,
manifest: manifestRouter, manifest: manifestRouter,
'network-interface': networkInterfaceRouter, 'network-interface': networkInterfaceRouter,
server: serverRouter, server: serverRouter,

@ -0,0 +1,20 @@
import express from 'express';
import {
createMailRecipient,
deleteMailRecipient,
getMailRecipient,
getMailRecipientDetail,
updateMailRecipient,
} from '../lib/request_handlers/mail-recipient';
const router = express.Router();
router
.delete('/:uuid', deleteMailRecipient)
.get('/', getMailRecipient)
.get('/:uuid', getMailRecipientDetail)
.post('/', createMailRecipient)
.put('/:uuid', updateMailRecipient);
export default router;

@ -0,0 +1,20 @@
import express from 'express';
import {
createMailServer,
deleteMailServer,
getMailServer,
getMailServerDetail,
updateMailServer,
} from '../lib/request_handlers/mail-server';
const router = express.Router();
router
.delete('/:uuid', deleteMailServer)
.get('/', getMailServer)
.get('/:uuid', getMailServerDetail)
.post('/', createMailServer)
.put('/:uuid', updateMailServer);
export default router;

@ -0,0 +1,26 @@
type AlertOverrideOverview = {
level: number;
mailRecipient: MailRecipientOverview;
node: { name: string; uuid: string };
subnode: { name: string; short: string; uuid: string };
uuid: string;
};
type AlertOverrideDetail = AlertOverrideOverview;
type AlertOverrideOverviewList = {
[uuid: string]: AlertOverrideOverview;
};
type AlertOverrideReqQuery = {
'mail-recipient': string | string[];
};
type AlertOverrideReqParams = {
uuid: string;
};
type AlertOverrideRequestBody = Pick<AlertOverrideDetail, 'level'> & {
hostUuid: string;
mailRecipientUuid: string;
};

@ -0,0 +1,22 @@
type MailRecipientOverview = {
name: string;
uuid: string;
};
type MailRecipientDetail = MailRecipientOverview & {
email: string;
language: string;
level: number;
};
type MailRecipientOverviewList = {
[uuid: string]: MailRecipientOverview;
};
type MailRecipientParamsDictionary = {
uuid: string;
};
type MailRecipientRequestBody = Omit<MailRecipientDetail, 'uuid'>;
type MailRecipientResponseBody = Pick<MailRecipientDetail, 'uuid'>;

@ -0,0 +1,23 @@
type MailServerOverview = {
address: string;
port: number;
uuid: string;
};
type MailServerDetail = MailServerOverview & {
authentication: string;
heloDomain: string;
password?: string;
security: string;
username?: string;
};
type MailServerOverviewList = {
[uuid: string]: MailServerOverview;
};
type MailServerParamsDictionary = {
uuid: string;
};
type MailServerRequestBody = Omit<MailServerDetail, 'uuid'>;
Loading…
Cancel
Save