Chore: Convert email inbox feature to TypeScript (#25298)

* chore: email-inbox rest types

* Fix email inbox types

* Email inbox endpoints to TS

* Fix email-inbox params

* Chore: Lib emailInbox to ts

* chore: migrate to typescript

* chore: fix lint

* chore: fix table sort

* Fix endpoint types

* Chore: methods to insert and update was splitted

* Removed the wrong validation

* Back to default types for sort and query

* Purge build files before compile

* Require some fields of `IEmailInbox`

* Fix weird destructuring

Co-authored-by: albuquerquefabio <albuquerquefabio@icloud.com>
Co-authored-by: Tasso Evangelista <tasso.evangelista@rocket.chat>
pull/25468/head
Jorge Leite 4 years ago committed by GitHub
parent c06874392b
commit ee1d14618f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      _templates/package/new/package.json.ejs.t
  2. 79
      apps/meteor/app/api/server/lib/emailInbox.js
  3. 101
      apps/meteor/app/api/server/lib/emailInbox.ts
  4. 62
      apps/meteor/app/api/server/v1/email-inbox.ts
  5. 12
      apps/meteor/client/views/admin/emailInbox/EmailInboxEditWithData.tsx
  6. 82
      apps/meteor/client/views/admin/emailInbox/EmailInboxTable.js
  7. 128
      apps/meteor/client/views/admin/emailInbox/EmailInboxTable.tsx
  8. 27
      apps/meteor/client/views/admin/emailInbox/SendTestButton.js
  9. 34
      apps/meteor/client/views/admin/emailInbox/SendTestButton.tsx
  10. 6
      apps/meteor/client/views/admin/emailInbox/Skeleton.tsx
  11. 5
      apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
  12. 2
      packages/core-typings/package.json
  13. 2
      packages/rest-typings/package.json
  14. 2
      packages/rest-typings/src/index.ts
  15. 45
      packages/rest-typings/src/v1/email-inbox.ts
  16. 2
      packages/ui-contexts/package.json

@ -17,7 +17,7 @@ to: packages/<%= name %>/package.json
"lint": "eslint --ext .js,.jsx,.ts,.tsx .",
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx . --fix",
"jest": "jest",
"build": "tsc -p tsconfig.json"
"build": "rm -rf dist && tsc -p tsconfig.json"
},
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",

@ -1,79 +0,0 @@
import { EmailInbox } from '../../../models/server/raw';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { Users } from '../../../models';
export async function findEmailInboxes({ userId, query = {}, pagination: { offset, count, sort } }) {
if (!(await hasPermissionAsync(userId, 'manage-email-inbox'))) {
throw new Error('error-not-allowed');
}
const cursor = EmailInbox.find(query, {
sort: sort || { name: 1 },
skip: offset,
limit: count,
});
const total = await cursor.count();
const emailInboxes = await cursor.toArray();
return {
emailInboxes,
count: emailInboxes.length,
offset,
total,
};
}
export async function findOneEmailInbox({ userId, _id }) {
if (!(await hasPermissionAsync(userId, 'manage-email-inbox'))) {
throw new Error('error-not-allowed');
}
return EmailInbox.findOneById(_id);
}
export async function insertOneOrUpdateEmailInbox(userId, emailInboxParams) {
const { _id, active, name, email, description, senderInfo, department, smtp, imap } = emailInboxParams;
if (!_id) {
emailInboxParams._createdAt = new Date();
emailInboxParams._updatedAt = new Date();
emailInboxParams._createdBy = Users.findOne(userId, { fields: { username: 1 } });
return EmailInbox.insertOne(emailInboxParams);
}
const emailInbox = await findOneEmailInbox({ userId, id: _id });
if (!emailInbox) {
throw new Error('error-invalid-email-inbox');
}
const updateEmailInbox = {
$set: {
active,
name,
email,
description,
senderInfo,
smtp,
imap,
_updatedAt: new Date(),
},
};
if (department === 'All') {
updateEmailInbox.$unset = {
department: 1,
};
} else {
updateEmailInbox.$set.department = department;
}
return EmailInbox.updateOne({ _id }, updateEmailInbox);
}
export async function findOneEmailInboxByEmail({ userId, email }) {
if (!(await hasPermissionAsync(userId, 'manage-email-inbox'))) {
throw new Error('error-not-allowed');
}
return EmailInbox.findOne({ email });
}

@ -0,0 +1,101 @@
import { IEmailInbox } from '@rocket.chat/core-typings';
import { InsertOneWriteOpResult, UpdateWriteOpResult, WithId } from 'mongodb';
import { EmailInbox } from '../../../models/server/raw';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { Users } from '../../../models/server';
export const findEmailInboxes = async ({
userId,
query = {},
pagination: { offset, count, sort },
}: {
userId: string;
query?: {};
pagination: {
offset: number;
count: number;
sort?: {};
};
}): Promise<{
emailInboxes: IEmailInbox[];
total: number;
count: number;
offset: number;
}> => {
if (!(await hasPermissionAsync(userId, 'manage-email-inbox'))) {
throw new Error('error-not-allowed');
}
const cursor = EmailInbox.find(query, {
sort: sort || { name: 1 },
skip: offset,
limit: count,
});
const total = await cursor.count();
const emailInboxes = await cursor.toArray();
return {
emailInboxes,
count: emailInboxes.length,
offset,
total,
};
};
export const findOneEmailInbox = async ({ userId, _id }: { userId: string; _id: string }): Promise<IEmailInbox | null> => {
if (!(await hasPermissionAsync(userId, 'manage-email-inbox'))) {
throw new Error('error-not-allowed');
}
return EmailInbox.findOneById(_id);
};
export const insertOneEmailInbox = async (
userId: string,
emailInboxParams: Pick<IEmailInbox, 'active' | 'name' | 'email' | 'description' | 'senderInfo' | 'department' | 'smtp' | 'imap'>,
): Promise<InsertOneWriteOpResult<WithId<IEmailInbox>>> => {
const obj = {
...emailInboxParams,
_createdAt: new Date(),
_updatedAt: new Date(),
_createdBy: Users.findOne(userId, { fields: { username: 1 } }),
};
return EmailInbox.insertOne(obj);
};
export const updateEmailInbox = async (
userId: string,
emailInboxParams: Pick<IEmailInbox, '_id' | 'active' | 'name' | 'email' | 'description' | 'senderInfo' | 'department' | 'smtp' | 'imap'>,
): Promise<InsertOneWriteOpResult<WithId<IEmailInbox>> | UpdateWriteOpResult> => {
const { _id, active, name, email, description, senderInfo, department, smtp, imap } = emailInboxParams;
const emailInbox = await findOneEmailInbox({ userId, _id });
if (!emailInbox) {
throw new Error('error-invalid-email-inbox');
}
const updateEmailInbox = {
$set: {
active,
name,
email,
description,
senderInfo,
smtp,
imap,
_updatedAt: new Date(),
...(department !== 'All' && { department }),
},
...(department === 'All' && { $unset: { department: 1 as const } }),
};
return EmailInbox.updateOne({ _id }, updateEmailInbox);
};
export const findOneEmailInboxByEmail = async ({ userId, email }: { userId: string; email: string }): Promise<IEmailInbox | null> => {
if (!(await hasPermissionAsync(userId, 'manage-email-inbox'))) {
throw new Error('error-not-allowed');
}
return EmailInbox.findOne({ email });
};

@ -1,7 +1,7 @@
import { check, Match } from 'meteor/check';
import { API } from '../api';
import { findEmailInboxes, findOneEmailInbox, insertOneOrUpdateEmailInbox } from '../lib/emailInbox';
import { insertOneEmailInbox, findEmailInboxes, findOneEmailInbox, updateEmailInbox } from '../lib/emailInbox';
import { hasPermission } from '../../../authorization/server/functions/hasPermission';
import { EmailInbox } from '../../../models/server/raw';
import Users from '../../../models/server/models/Users';
@ -11,10 +11,10 @@ API.v1.addRoute(
'email-inbox.list',
{ authRequired: true },
{
get() {
async get() {
const { offset, count } = this.getPaginationItems();
const { sort, query } = this.parseJsonQuery();
const emailInboxes = Promise.await(findEmailInboxes({ userId: this.userId, query, pagination: { offset, count, sort } }));
const emailInboxes = await findEmailInboxes({ userId: this.userId, query, pagination: { offset, count, sort } });
return API.v1.success(emailInboxes);
},
@ -25,40 +25,45 @@ API.v1.addRoute(
'email-inbox',
{ authRequired: true },
{
post() {
async post() {
if (!hasPermission(this.userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
check(this.bodyParams, {
_id: Match.Maybe(String),
active: Boolean,
name: String,
email: String,
active: Boolean,
description: Match.Maybe(String),
senderInfo: Match.Maybe(String),
department: Match.Maybe(String),
description: String,
senderInfo: String,
department: String,
smtp: Match.ObjectIncluding({
password: String,
port: Number,
secure: Boolean,
server: String,
port: Number,
username: String,
}),
imap: Match.ObjectIncluding({
password: String,
port: Number,
secure: Boolean,
}),
imap: Match.ObjectIncluding({
server: String,
port: Number,
username: String,
password: String,
secure: Boolean,
}),
});
const emailInboxParams = this.bodyParams;
const { _id } = emailInboxParams;
Promise.await(insertOneOrUpdateEmailInbox(this.userId, emailInboxParams));
let _id: string;
if (!emailInboxParams?._id) {
const emailInbox = await insertOneEmailInbox(this.userId, emailInboxParams);
_id = emailInbox.insertedId.toString();
} else {
_id = emailInboxParams._id;
await updateEmailInbox(this.userId, { ...emailInboxParams, _id });
}
return API.v1.success({ _id });
},
},
@ -68,7 +73,7 @@ API.v1.addRoute(
'email-inbox/:_id',
{ authRequired: true },
{
get() {
async get() {
check(this.urlParams, {
_id: String,
});
@ -77,11 +82,12 @@ API.v1.addRoute(
if (!_id) {
throw new Error('error-invalid-param');
}
const emailInboxes = Promise.await(findOneEmailInbox({ userId: this.userId, _id }));
// TODO: Chapter day backend - check if user has permission to view this email inbox instead of null values
const emailInboxes = await findOneEmailInbox({ userId: this.userId, _id });
return API.v1.success(emailInboxes);
},
delete() {
async delete() {
if (!hasPermission(this.userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
@ -94,12 +100,12 @@ API.v1.addRoute(
throw new Error('error-invalid-param');
}
const emailInboxes = Promise.await(EmailInbox.findOneById(_id));
const emailInboxes = await EmailInbox.findOneById(_id);
if (!emailInboxes) {
return API.v1.notFound();
}
Promise.await(EmailInbox.removeById(_id));
await EmailInbox.removeById(_id);
return API.v1.success({ _id });
},
},
@ -109,7 +115,7 @@ API.v1.addRoute(
'email-inbox.search',
{ authRequired: true },
{
get() {
async get() {
if (!hasPermission(this.userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
@ -118,7 +124,9 @@ API.v1.addRoute(
});
const { email } = this.queryParams;
const emailInbox = Promise.await(EmailInbox.findOne({ email }));
// TODO: Chapter day backend - check if user has permission to view this email inbox instead of null values
const emailInbox = await EmailInbox.findOne({ email });
return API.v1.success({ emailInbox });
},
@ -129,7 +137,7 @@ API.v1.addRoute(
'email-inbox.send-test/:_id',
{ authRequired: true },
{
post() {
async post() {
if (!hasPermission(this.userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
@ -141,7 +149,7 @@ API.v1.addRoute(
if (!_id) {
throw new Error('error-invalid-param');
}
const emailInbox = Promise.await(findOneEmailInbox({ userId: this.userId, _id }));
const emailInbox = await findOneEmailInbox({ userId: this.userId, _id });
if (!emailInbox) {
return API.v1.notFound();
@ -149,7 +157,7 @@ API.v1.addRoute(
const user = Users.findOneById(this.userId);
Promise.await(sendTestEmailToInbox(emailInbox, user));
await sendTestEmailToInbox(emailInbox, user);
return API.v1.success({ _id });
},

@ -1,13 +1,17 @@
import { Box } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';
import React, { ReactElement } from 'react';
import { AsyncStatePhase } from '../../../hooks/useAsyncState';
import { useEndpointData } from '../../../hooks/useEndpointData';
import EmailInboxForm from './EmailInboxForm';
import { FormSkeleton } from './Skeleton';
function EmailInboxEditWithData({ id }) {
type EmailInboxEditWithDataProps = {
id: string;
};
const EmailInboxEditWithData = ({ id }: EmailInboxEditWithDataProps): ReactElement => {
const t = useTranslation();
const { value: data, error, phase: state } = useEndpointData(`email-inbox/${id}`);
@ -16,10 +20,10 @@ function EmailInboxEditWithData({ id }) {
}
if (error || !data) {
return <Box mbs='x16'>{t('EmailInbox_not_found')}</Box>;
return <Box mbs='x16'>{t('error-email-inbox-not-found')}</Box>;
}
return <EmailInboxForm id={id} data={data} />;
}
};
export default EmailInboxEditWithData;

@ -1,82 +0,0 @@
import { Table } from '@rocket.chat/fuselage';
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import { useRoute, useTranslation } from '@rocket.chat/ui-contexts';
import React, { useMemo, useCallback, useState } from 'react';
import GenericTable from '../../../components/GenericTable';
import { useEndpointData } from '../../../hooks/useEndpointData';
import SendTestButton from './SendTestButton';
const useQuery = ({ itemsPerPage, current }, [column, direction]) =>
useMemo(
() => ({
sort: JSON.stringify({ [column]: direction === 'asc' ? 1 : -1 }),
...(itemsPerPage && { count: itemsPerPage }),
...(current && { offset: current }),
}),
[column, current, direction, itemsPerPage],
);
function EmailInboxTable() {
const t = useTranslation();
const [params, setParams] = useState({ current: 0, itemsPerPage: 25 });
const [sort] = useState(['name', 'asc']);
const debouncedParams = useDebouncedValue(params, 500);
const debouncedSort = useDebouncedValue(sort, 500);
const query = useQuery(debouncedParams, debouncedSort);
const router = useRoute('admin-email-inboxes');
const onClick = useCallback(
(_id) => () =>
router.push({
context: 'edit',
_id,
}),
[router],
);
const header = useMemo(
() =>
[
<GenericTable.HeaderCell key={'name'} direction={sort[1]} active={sort[0] === 'name'}>
{t('Name')}
</GenericTable.HeaderCell>,
<GenericTable.HeaderCell key={'email'} direction={sort[1]} active={sort[0] === 'email'}>
{t('Email')}
</GenericTable.HeaderCell>,
<GenericTable.HeaderCell key={'active'} direction={sort[1]} active={sort[0] === 'active'}>
{t('Active')}
</GenericTable.HeaderCell>,
<GenericTable.HeaderCell key={'sendTest'} w='x60'></GenericTable.HeaderCell>,
].filter(Boolean),
[sort, t],
);
const { value: data } = useEndpointData('email-inbox.list', query);
const renderRow = useCallback(
({ _id, name, email, active }) => (
<Table.Row action key={_id} onKeyDown={onClick(_id)} onClick={onClick(_id)} tabIndex={0} role='link' qa-room-id={_id}>
<Table.Cell withTruncatedText>{name}</Table.Cell>
<Table.Cell withTruncatedText>{email}</Table.Cell>
<Table.Cell withTruncatedText>{active ? t('Yes') : t('No')}</Table.Cell>
<SendTestButton id={_id} />
</Table.Row>
),
[onClick, t],
);
return (
<GenericTable
header={header}
renderRow={renderRow}
results={data && data.emailInboxes}
total={data && data.total}
setParams={setParams}
params={params}
/>
);
}
export default EmailInboxTable;

@ -0,0 +1,128 @@
import { Box, Pagination } from '@rocket.chat/fuselage';
import { useRoute, useTranslation } from '@rocket.chat/ui-contexts';
import React, { useMemo, useCallback, ReactElement } from 'react';
import {
GenericTable,
GenericTableBody,
GenericTableCell,
GenericTableHeader,
GenericTableHeaderCell,
GenericTableLoadingTable,
GenericTableRow,
} from '../../../components/GenericTable';
import { usePagination } from '../../../components/GenericTable/hooks/usePagination';
import { useSort } from '../../../components/GenericTable/hooks/useSort';
import { useEndpointData } from '../../../hooks/useEndpointData';
import { AsyncStatePhase } from '../../../lib/asyncState/AsyncStatePhase';
import SendTestButton from './SendTestButton';
const useQuery = (
{
itemsPerPage,
current,
}: {
itemsPerPage: number;
current: number;
},
[column, direction]: string[],
): {
offset?: number;
count?: number;
sort: string;
} =>
useMemo(
() => ({
sort: JSON.stringify({ [column]: direction === 'asc' ? 1 : -1 }),
...(itemsPerPage && { count: itemsPerPage }),
...(current && { offset: current }),
}),
[column, current, direction, itemsPerPage],
);
const EmailInboxTable = (): ReactElement => {
const t = useTranslation();
const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination();
const { sortBy, sortDirection, setSort } = useSort<'name'>('name');
const query = useQuery({ itemsPerPage, current }, [sortBy, sortDirection]);
const router = useRoute('admin-email-inboxes');
const onClick = useCallback(
(_id) => (): void => {
router.push({
context: 'edit',
_id,
});
},
[router],
);
const { phase, value: { emailInboxes = [], count = 0 } = {} } = useEndpointData('email-inbox.list', query);
return (
<>
<GenericTable>
<GenericTableHeader>
<GenericTableHeaderCell key='name' direction={sortDirection} active={sortBy === 'name'} onClick={setSort} sort='name' w='x200'>
{t('Name')}
</GenericTableHeaderCell>
<GenericTableHeaderCell key='email' direction={sortDirection} active={sortBy === 'name'} onClick={setSort} sort='name' w='x200'>
{t('Email')}
</GenericTableHeaderCell>
<GenericTableHeaderCell key='active' direction={sortDirection} active={sortBy === 'name'} onClick={setSort} sort='name' w='x200'>
{t('Active')}
</GenericTableHeaderCell>
<GenericTableHeaderCell
key='sendTest'
direction={sortDirection}
active={sortBy === 'name'}
onClick={setSort}
sort='name'
w='x200'
></GenericTableHeaderCell>
</GenericTableHeader>
<GenericTableBody>
{phase === AsyncStatePhase.LOADING && <GenericTableLoadingTable headerCells={2} />}
{phase === AsyncStatePhase.RESOLVED &&
count > 0 &&
emailInboxes.map((emailInbox) => (
<GenericTableRow
key={emailInbox._id}
onKeyDown={onClick(emailInbox._id)}
onClick={onClick(emailInbox._id)}
tabIndex={0}
role='link'
action
width='full'
>
<GenericTableCell fontScale='p1' color='default'>
<Box withTruncatedText>{emailInbox.name}</Box>
</GenericTableCell>
<GenericTableCell fontScale='p1' color='default'>
<Box withTruncatedText>{emailInbox.email}</Box>
</GenericTableCell>
<GenericTableCell fontScale='p1' color='default'>
<Box withTruncatedText>{emailInbox.active ? t('Yes') : t('No')}</Box>
</GenericTableCell>
<SendTestButton id={emailInbox._id} />
</GenericTableRow>
))}
</GenericTableBody>
</GenericTable>
{phase === AsyncStatePhase.RESOLVED && (
<Pagination
current={current}
itemsPerPage={itemsPerPage}
count={count}
onSetItemsPerPage={onSetItemsPerPage}
onSetCurrent={onSetCurrent}
{...paginationProps}
/>
)}
</>
);
};
export default EmailInboxTable;

@ -1,27 +0,0 @@
import { Button, Table, Icon } from '@rocket.chat/fuselage';
import { useToastMessageDispatch, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';
function SendTestButton({ id }) {
const t = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();
const sendTest = useEndpoint('POST', `email-inbox.send-test/${id}`);
return (
<Table.Cell fontScale='p2' color='hint' withTruncatedText>
<Button
small
ghost
title={t('Send_Test_Email')}
onClick={(e) =>
e.preventDefault() & e.stopPropagation() & sendTest() & dispatchToastMessage({ type: 'success', message: t('Email_sent') })
}
>
<Icon name='send' size='x20' />
</Button>
</Table.Cell>
);
}
export default SendTestButton;

@ -0,0 +1,34 @@
import { Button, Icon, TableCell } from '@rocket.chat/fuselage';
import { useToastMessageDispatch, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts';
import React, { ReactElement } from 'react';
type SendTestButtonProps = {
id: string;
};
const SendTestButton = ({ id }: SendTestButtonProps): ReactElement => {
const t = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();
const sendTest = useEndpoint('POST', `email-inbox.send-test/${id}`);
const handleOnClick = (e: React.MouseEvent<HTMLElement, MouseEvent>): void => {
e.preventDefault();
e.stopPropagation();
sendTest();
dispatchToastMessage({
type: 'success',
message: t('Email_sent'),
});
};
return (
<TableCell fontScale='p2' color='hint' withTruncatedText>
<Button small ghost title={t('Send_Test_Email')} onClick={handleOnClick}>
<Icon name='send' size='x20' />
</Button>
</TableCell>
);
};
export default SendTestButton;

@ -1,8 +1,8 @@
import { Box, Skeleton } from '@rocket.chat/fuselage';
import React from 'react';
import React, { ReactElement } from 'react';
export const FormSkeleton = (props) => (
<Box w='full' pb='x24' {...props}>
export const FormSkeleton = (): ReactElement => (
<Box w='full' pb='x24'>
<Skeleton mbe='x8' />
<Skeleton mbe='x4' />
<Skeleton mbe='x4' />

@ -1747,6 +1747,7 @@
"error-invalid-email": "Invalid email __email__",
"error-invalid-email-address": "Invalid email address",
"error-invalid-email-inbox": "Invalid Email Inbox",
"error-email-inbox-not-found": "Email Inbox not found",
"error-invalid-file-height": "Invalid file height",
"error-invalid-file-type": "Invalid file type",
"error-invalid-file-width": "Invalid file width",
@ -3360,8 +3361,8 @@
"OTR": "OTR",
"OTR_Chat_Declined_Title": "OTR Chat invite Declined",
"OTR_Chat_Declined_Description": "%s declined OTR chat invite. For privacy protection local cache was deleted, including all related system messages.",
"OTR_Chat_Error_Title":"Chat ended due to failed key refresh",
"OTR_Chat_Error_Description":"For privacy protection local cache was deleted, including all related system messages.",
"OTR_Chat_Error_Title": "Chat ended due to failed key refresh",
"OTR_Chat_Error_Description": "For privacy protection local cache was deleted, including all related system messages.",
"OTR_Chat_Timeout_Title": "OTR chat invite expired",
"OTR_Chat_Timeout_Description": "%s failed to accept OTR chat invite in time. For privacy protection local cache was deleted, including all related system messages.",
"OTR_Enable_Description": "Enable option to use off-the-record (OTR) messages in direct messages between 2 users. OTR messages are not recorded on the server and exchanged directly and encrypted between the 2 users.",

@ -17,7 +17,7 @@
"lint": "eslint --ext .js,.jsx,.ts,.tsx .",
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx . --fix",
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc -p tsconfig.json"
"build": "rm -rf dist && tsc -p tsconfig.json"
},
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",

@ -19,7 +19,7 @@
"lint": "eslint --ext .js,.jsx,.ts,.tsx .",
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx . --fix",
"jest": "jest",
"build": "tsc -p tsconfig.json"
"build": "rm -rf dist && tsc -p tsconfig.json"
},
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",

@ -31,6 +31,7 @@ import type { TeamsEndpoints } from './v1/teams';
import type { UsersEndpoints } from './v1/users';
import type { VideoConferenceEndpoints } from './v1/videoConference';
import type { VoipEndpoints } from './v1/voip';
import type { EmailInboxEndpoints } from './v1/email-inbox';
import type { WebdavEndpoints } from './v1/webdav';
import type { OAuthAppsEndpoint } from './v1/oauthapps';
@ -65,6 +66,7 @@ export interface Endpoints
InvitesEndpoints,
E2eEndpoints,
CustomSoundEndpoint,
EmailInboxEndpoints,
WebdavEndpoints,
OAuthAppsEndpoint {}

@ -0,0 +1,45 @@
import type { IEmailInbox } from '@rocket.chat/core-typings';
import type { PaginatedRequest } from '../helpers/PaginatedRequest';
import type { PaginatedResult } from '../helpers/PaginatedResult';
export type EmailInboxEndpoints = {
'email-inbox.list': {
GET: (params: PaginatedRequest<{ query?: string }>) => PaginatedResult<{ emailInboxes: IEmailInbox[] }>;
};
'email-inbox': {
POST: (params: {
_id?: string;
name: string;
email: string;
active: boolean;
description: string;
senderInfo: string;
department: string;
smtp: {
password: string;
port: number;
secure: boolean;
server: string;
username: string;
};
imap: {
password: string;
port: number;
secure: boolean;
server: string;
username: string;
};
}) => { _id: string };
};
'email-inbox/:_id': {
GET: (params: void) => IEmailInbox | null;
DELETE: (params: void) => { _id: string };
};
'email-inbox.search': {
GET: (params: { email: string }) => { emailInbox: IEmailInbox | null };
};
'email-inbox.send-test/:_id': {
POST: (params: void) => { _id: string };
};
};

@ -30,7 +30,7 @@
"lint": "eslint --ext .js,.jsx,.ts,.tsx .",
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx . --fix",
"jest": "jest",
"build": "tsc -p tsconfig.json"
"build": "rm -rf dist && tsc -p tsconfig.json"
},
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",

Loading…
Cancel
Save