This commit is contained in:
Simon Larsen
2023-09-06 21:38:00 +05:30
parent eb20310990
commit d0b2667b25
24 changed files with 367 additions and 206 deletions

View File

@@ -18,7 +18,7 @@ import Projects from './Pages/Projects/Index';
import Users from './Pages/Users/Index';
import Logout from './Pages/Logout/Logout';
// Settings Pages.
// Settings Pages.
import SettingsHost from './Pages/Settings/Host/Index';
import SettingsEmail from './Pages/Settings/SMTP/Index';
import SettingsCallSMS from './Pages/Settings/CallSMS/Index';
@@ -73,7 +73,6 @@ const App: () => JSX.Element = () => {
element={<SettingsHost />}
/>
<PageRoute
path={RouteMap[PageMap.SETTINGS_HOST]?.toString() || ''}
element={<SettingsHost />}
@@ -85,10 +84,12 @@ const App: () => JSX.Element = () => {
/>
<PageRoute
path={RouteMap[PageMap.SETTINGS_CALL_AND_SMS]?.toString() || ''}
path={
RouteMap[PageMap.SETTINGS_CALL_AND_SMS]?.toString() ||
''
}
element={<SettingsCallSMS />}
/>
</Routes>
</MasterPage>
);

View File

@@ -6,13 +6,11 @@ import RouteMap from '../../Utils/RouteMap';
import PageMap from '../../Utils/PageMap';
const Init: FunctionComponent = (): ReactElement => {
useEffect(() => {
Navigation.navigate(RouteMap[PageMap.USERS]!, {
forceNavigate: true
forceNavigate: true,
});
},[]);
}, []);
return (
<Page title={''} breadcrumbLinks={[]}>

View File

@@ -10,9 +10,7 @@ import Navigation from 'CommonUI/src/Utils/Navigation';
import { ACCOUNTS_URL } from 'CommonUI/src/Config';
import UiAnalytics from 'CommonUI/src/Utils/Analytics';
const Logout: FunctionComponent = (
): ReactElement => {
const Logout: FunctionComponent = (): ReactElement => {
useEffect(() => {
UiAnalytics.logout();
UserUtil.logout();

View File

@@ -10,9 +10,7 @@ import GlobalConfig from 'Model/Models/GlobalConfig';
import ObjectID from 'Common/Types/ObjectID';
import FieldType from 'CommonUI/src/Components/Types/FieldType';
const Settings: FunctionComponent = (
): ReactElement => {
const Settings: FunctionComponent = (): ReactElement => {
return (
<Page
title={'Admin Settings'}
@@ -46,7 +44,7 @@ const Settings: FunctionComponent = (
description: 'This will be used to make Call and send SMS.',
}}
isEditable={true}
editButtonText='Edit Twilio Config'
editButtonText="Edit Twilio Config"
formFields={[
{
field: {
@@ -55,7 +53,8 @@ const Settings: FunctionComponent = (
title: 'Twilio Account SID',
fieldType: FormFieldSchemaType.Text,
required: true,
description: 'You can find this in your Twilio console.',
description:
'You can find this in your Twilio console.',
placeholder: '',
validation: {
minLength: 2,
@@ -68,7 +67,8 @@ const Settings: FunctionComponent = (
title: 'Twilio Auth Token',
fieldType: FormFieldSchemaType.Text,
required: true,
description: 'You can find this in your Twilio console.',
description:
'You can find this in your Twilio console.',
placeholder: '',
validation: {
minLength: 2,
@@ -81,7 +81,8 @@ const Settings: FunctionComponent = (
title: 'Twilio Phone Number',
fieldType: FormFieldSchemaType.Phone,
required: true,
description: 'You can find this in your Twilio console.',
description:
'You can find this in your Twilio console.',
placeholder: '',
validation: {
minLength: 2,
@@ -97,14 +98,14 @@ const Settings: FunctionComponent = (
twilioAccountSID: true,
},
title: 'Twilio Account SID',
placeholder: 'None'
placeholder: 'None',
},
{
field: {
twilioAuthToken: true,
},
title: 'Twilio Auth Token',
placeholder: 'None'
placeholder: 'None',
},
{
field: {
@@ -112,9 +113,8 @@ const Settings: FunctionComponent = (
},
title: 'Twilio Phone Number',
fieldType: FieldType.Phone,
placeholder: 'None'
placeholder: 'None',
},
],
modelId: ObjectID.getZeroObjectID(),
}}

View File

@@ -9,9 +9,7 @@ import DashboardSideMenu from '../SideMenu';
import GlobalConfig from 'Model/Models/GlobalConfig';
import ObjectID from 'Common/Types/ObjectID';
const Settings: FunctionComponent = (
): ReactElement => {
const Settings: FunctionComponent = (): ReactElement => {
return (
<Page
title={'Admin Settings'}
@@ -42,10 +40,11 @@ const Settings: FunctionComponent = (
name="Host Settings"
cardProps={{
title: 'Host Settings',
description: 'Host Settings for this OneUptime Server instance.',
description:
'Host Settings for this OneUptime Server instance.',
}}
isEditable={true}
editButtonText='Edit Host'
editButtonText="Edit Host"
formFields={[
{
field: {
@@ -54,7 +53,8 @@ const Settings: FunctionComponent = (
title: 'Host',
fieldType: FormFieldSchemaType.Text,
required: true,
description: 'IP address or Hostname of this server instance.',
description:
'IP address or Hostname of this server instance.',
placeholder: 'oneuptime.yourcompany.com',
validation: {
minLength: 2,
@@ -71,7 +71,8 @@ const Settings: FunctionComponent = (
},
title: 'Host',
placeholder: 'None',
description: 'IP address or Hostname of this server instance.',
description:
'IP address or Hostname of this server instance.',
},
],
modelId: ObjectID.getZeroObjectID(),

View File

@@ -0,0 +1,240 @@
import Route from 'Common/Types/API/Route';
import Page from 'CommonUI/src/Components/Page/Page';
import React, { FunctionComponent, ReactElement, useState } from 'react';
import PageMap from '../../../Utils/PageMap';
import RouteMap, { RouteUtil } from '../../../Utils/RouteMap';
import DashboardSideMenu from '../SideMenu';
import ModelTable from 'CommonUI/src/Components/ModelTable/ModelTable';
import Probe from 'Model/Models/Probe';
import FieldType from 'CommonUI/src/Components/Types/FieldType';
import { JSONObject } from 'Common/Types/JSON';
import OneUptimeDate from 'Common/Types/Date';
import { Green, Red } from 'Common/Types/BrandColors';
import Statusbubble from 'CommonUI/src/Components/StatusBubble/StatusBubble';
import ProbeElement from 'CommonUI/src/Components/Probe/Probe'
import IsNull from 'Common/Types/Database/IsNull';
import Banner from 'CommonUI/src/Components/Banner/Banner';
import URL from 'Common/Types/API/URL';
import FormFieldSchemaType from 'CommonUI/src/Components/Forms/Types/FormFieldSchemaType';
import { ButtonStyleType } from 'CommonUI/src/Components/Button/Button';
import ConfirmModal from 'CommonUI/src/Components/Modal/ConfirmModal';
const Settings: FunctionComponent = (
): ReactElement => {
const [showKeyModal, setShowKeyModal] = useState<boolean>(false);
const [currentProbe, setCurrentProbe] = useState<JSONObject | null>(null);
return (
<Page
title={'Admin Settings'}
breadcrumbLinks={[
{
title: 'Admin Dashboard',
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.HOME] as Route
),
},
{
title: 'Settings',
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.SETTINGS] as Route
),
},
{
title: 'Global Probes',
to: RouteUtil.populateRouteParams(
RouteMap[PageMap.SETTINGS_PROBES] as Route
),
},
]}
sideMenu={<DashboardSideMenu />}
>
{/* Project Settings View */}
<Banner
openInNewTab={true}
title="Need help with setting up Global Probes?"
description="Here is a guide which will help you get set up"
link={URL.fromString(
'https://github.com/OneUptime/oneuptime/blob/master/Docs/Probe/CustomProbe.md'
)}
/>
<ModelTable<Probe>
modelType={Probe}
id="probes-table"
name="Settings > Global Probes"
isDeleteable={true}
isEditable={true}
isCreateable={true}
cardProps={{
title: 'Global Probes',
description:
'Global Probes help you monitor external resources from different locations around the world.',
}}
query={{
projectId: new IsNull()
}}
noItemsMessage={'No probes found.'}
showRefreshButton={true}
showFilterButton={true}
formFields={[
{
field: {
name: true,
},
title: 'Name',
fieldType: FormFieldSchemaType.Text,
required: true,
placeholder: 'internal-probe',
validation: {
minLength: 2,
},
},
{
field: {
description: true,
},
title: 'Description',
fieldType: FormFieldSchemaType.LongText,
required: true,
placeholder:
'This probe is to monitor all the internal services.',
},
{
field: {
iconFile: true,
},
title: 'Probe Logo',
fieldType: FormFieldSchemaType.ImageFile,
required: false,
placeholder: 'Upload logo',
}
]}
selectMoreFields={{
key: true,
iconFileId: true,
}}
actionButtons={[
{
title: 'Show ID and Key',
buttonStyleType: ButtonStyleType.NORMAL,
onClick: async (
item: JSONObject,
onCompleteAction: Function,
onError: (err: Error) => void
) => {
try {
setCurrentProbe(item);
setShowKeyModal(true);
onCompleteAction();
} catch (err) {
onCompleteAction();
onError(err as Error);
}
},
},
]}
columns={[
{
field: {
name: true,
},
title: 'Name',
type: FieldType.Text,
isFilterable: true,
getElement: (item: JSONObject): ReactElement => {
return <ProbeElement probe={item} />;
},
},
{
field: {
description: true,
},
title: 'Description',
type: FieldType.Text,
isFilterable: true,
},
{
field: {
lastAlive: true,
},
title: 'Status',
type: FieldType.Text,
isFilterable: false,
getElement: (item: JSONObject): ReactElement => {
if (
item &&
item['lastAlive'] &&
OneUptimeDate.getNumberOfMinutesBetweenDates(
OneUptimeDate.fromString(
item['lastAlive'] as string
),
OneUptimeDate.getCurrentDate()
) < 5
) {
return (
<Statusbubble
text={'Connected'}
color={Green}
/>
);
}
return (
<Statusbubble
text={'Disconnected'}
color={Red}
/>
);
},
},
]}
/>
{showKeyModal && currentProbe ? (
<ConfirmModal
title={`Probe Key`}
description={
<div>
<span>
Here is your probe key. Please keep this a
secret.
</span>
<br />
<br />
<span>
<b>Probe ID: </b>{' '}
{currentProbe['_id']?.toString()}
</span>
<br />
<br />
<span>
<b>Probe Key: </b>{' '}
{currentProbe['key']?.toString()}
</span>
</div>
}
submitButtonText={'Close'}
submitButtonType={ButtonStyleType.NORMAL}
onSubmit={async () => {
setShowKeyModal(false);
}}
/>
) : (
<></>
)}
</Page>
);
};
export default Settings;

View File

@@ -10,9 +10,7 @@ import GlobalConfig from 'Model/Models/GlobalConfig';
import ObjectID from 'Common/Types/ObjectID';
import FieldType from 'CommonUI/src/Components/Types/FieldType';
const Settings: FunctionComponent = (
): ReactElement => {
const Settings: FunctionComponent = (): ReactElement => {
return (
<Page
title={'Admin Settings'}
@@ -43,10 +41,11 @@ const Settings: FunctionComponent = (
name="Host Settings"
cardProps={{
title: 'Email and SMTP Settings',
description: 'Email and SMTP Settings. We will use this SMTP server to send all the emails.',
description:
'Email and SMTP Settings. We will use this SMTP server to send all the emails.',
}}
isEditable={true}
editButtonText='Edit SMTP Config'
editButtonText="Edit SMTP Config"
formSteps={[
{
title: 'SMTP Server',
@@ -145,21 +144,21 @@ const Settings: FunctionComponent = (
smtpHost: true,
},
title: 'SMTP Host',
placeholder: 'None'
placeholder: 'None',
},
{
field: {
smtpPort: true,
},
title: 'SMTP Port',
placeholder: 'None'
placeholder: 'None',
},
{
field: {
smtpUsername: true,
},
title: 'SMTP Username',
placeholder: 'None'
placeholder: 'None',
},
{
field: {
@@ -174,7 +173,7 @@ const Settings: FunctionComponent = (
smtpFromName: true,
},
title: 'SMTP From Name',
placeholder: 'None'
placeholder: 'None',
},
{
@@ -185,7 +184,6 @@ const Settings: FunctionComponent = (
placeholder: 'No',
fieldType: FieldType.Boolean,
},
],
modelId: ObjectID.getZeroObjectID(),
}}

View File

@@ -10,7 +10,6 @@ import PageMap from '../../Utils/PageMap';
const DashboardSideMenu: () => JSX.Element = (): ReactElement => {
return (
<SideMenu>
<SideMenuSection title="Basic">
<SideMenuItem
link={{
@@ -55,8 +54,6 @@ const DashboardSideMenu: () => JSX.Element = (): ReactElement => {
icon={IconProp.Signal}
/>
</SideMenuSection>
</SideMenu>
);
};

View File

@@ -6,7 +6,6 @@ enum PageMap {
USERS = 'USERS',
PROJECTS = 'PROJECTS',
SETTINGS_HOST = 'SETTINGS_HOST',
SETTINGS_SMTP = 'SETTINGS_SMTP',
SETTINGS_CALL_AND_SMS = 'SETTINGS_CALL_AND_SMS',

View File

@@ -15,7 +15,6 @@ const RouteMap: Dictionary<Route> = {
[PageMap.SETTINGS_SMTP]: new Route(`/admin/settings/smtp`),
[PageMap.SETTINGS_CALL_AND_SMS]: new Route(`/admin/settings/call-and-sms`),
[PageMap.SETTINGS_PROBES]: new Route(`/admin/settings/probes`),
};
export class RouteUtil {

View File

@@ -64,9 +64,8 @@ export default class ObjectID extends DatabaseProperty {
return null;
}
public static getZeroObjectID(): ObjectID {
return new ObjectID("00000000-0000-0000-0000-000000000000")
public static getZeroObjectID(): ObjectID {
return new ObjectID('00000000-0000-0000-0000-000000000000');
}
public static fromString(id: string): ObjectID {

View File

@@ -217,7 +217,6 @@ export default class BaseAPI<
public async getDatabaseCommonInteractionProps(
req: ExpressRequest
): Promise<DatabaseCommonInteractionProps> {
const props: DatabaseCommonInteractionProps = {
tenantId: undefined,
userGlobalAccessPermission: undefined,
@@ -263,9 +262,9 @@ export default class BaseAPI<
props.isSubscriptionUnpaid = plan.isSubscriptionUnpaid;
}
// check for root permissions.
// check for root permissions.
if(props.userType === UserType.MasterAdmin) {
if (props.userType === UserType.MasterAdmin) {
props.isRoot = true;
}

View File

@@ -175,31 +175,38 @@ class DatabaseService<TBaseModel extends BaseModel> extends BaseService {
return data;
}
protected async checkForUniqueValues(data: TBaseModel): Promise<TBaseModel> {
protected async checkForUniqueValues(
data: TBaseModel
): Promise<TBaseModel> {
const tableColumns: Array<string> = data.getTableColumns().columns;
for (const columnName of tableColumns) {
const metadata: TableColumnMetadata =
data.getTableColumnMetadata(columnName);
if (metadata.unique && data.getColumnValue(columnName)) {
// check for unique values.
// check for unique values.
const count: PositiveNumber = await this.countBy({
query: {
[columnName]: data.getColumnValue(columnName),
} as any,
props: {
isRoot: true
}
isRoot: true,
},
});
if(count.toNumber() > 0){
throw new BadDataException(`${metadata.title} ${data.getColumnValue(columnName)?.toString()} already exists. Please choose a different ${metadata.title}`);
if (count.toNumber() > 0) {
throw new BadDataException(
`${metadata.title} ${data
.getColumnValue(columnName)
?.toString()} already exists. Please choose a different ${
metadata.title
}`
);
}
}
}
return data;
return data;
}
protected checkRequiredFields(data: TBaseModel): TBaseModel {

View File

@@ -152,9 +152,7 @@ const ModelForm: <TBaseModel extends BaseModel>(
const hasPermissionOnField: (fieldName: string) => boolean = (
fieldName: string
): boolean => {
if(User.isMasterAdmin()){
if (User.isMasterAdmin()) {
return true; // master admin can do anything.
}

View File

@@ -48,20 +48,19 @@ const CardModelDetail: <TBaseModel extends BaseModel>(
const userProjectPermissions: UserTenantAccessPermission | null =
PermissionUtil.getProjectPermissions();
const hasPermissionToEdit: boolean = Boolean(
userProjectPermissions &&
userProjectPermissions.permissions &&
PermissionHelper.doesPermissionsIntersect(
model.updateRecordPermissions,
userProjectPermissions.permissions.map(
(item: UserPermission) => {
return item.permission;
}
const hasPermissionToEdit: boolean =
Boolean(
userProjectPermissions &&
userProjectPermissions.permissions &&
PermissionHelper.doesPermissionsIntersect(
model.updateRecordPermissions,
userProjectPermissions.permissions.map(
(item: UserPermission) => {
return item.permission;
}
)
)
)
) || User.isMasterAdmin();
) || User.isMasterAdmin();
let cardButtons: Array<CardButtonSchema> = [];

View File

@@ -114,15 +114,14 @@ const ModelDetail: <TBaseModel extends BaseModel>(
fieldPermissions = accessControl[key]?.read || [];
const hasPermissions = fieldPermissions &&
PermissionHelper.doesPermissionsIntersect(
userPermissions,
fieldPermissions
);
const hasPermissions: boolean =
fieldPermissions &&
PermissionHelper.doesPermissionsIntersect(
userPermissions,
fieldPermissions
);
if (
hasPermissions || User.isMasterAdmin()
) {
if (hasPermissions || User.isMasterAdmin()) {
fieldsToSet.push({
...field,
key: key,

View File

@@ -1,11 +1,11 @@
import { JSONObject } from 'Common/Types/JSON';
import JSONFunctions from 'Common/Types/JSONFunctions';
import React, { FunctionComponent, ReactElement } from 'react';
import Image from 'CommonUI/src/Components/Image/Image';
import Image from '../Image/Image';
import URL from 'Common/Types/API/URL';
import { FILE_URL } from 'CommonUI/src/Config';
import { FILE_URL } from '../../Config';
import Probe from 'Model/Models/Probe';
import Icon from 'CommonUI/src/Components/Icon/Icon';
import Icon from '../Icon/Icon';
import IconProp from 'Common/Types/Icon/IconProp';
export interface ComponentProps {

View File

@@ -22,7 +22,7 @@ import MonitorProbe from 'Model/Models/MonitorProbe';
import DashboardNavigation from '../../../Utils/Navigation';
import Probe from 'Model/Models/Probe';
import FieldType from 'CommonUI/src/Components/Types/FieldType';
import ProbeElement from '../../../Components/Probe/Probe';
import ProbeElement from 'CommonUI/src/Components/Probe/Probe';
import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax';
import URL from 'Common/Types/API/URL';
import { DASHBOARD_API_URL } from 'CommonUI/src/Config';

View File

@@ -14,7 +14,7 @@ import DashboardNavigation from '../../Utils/Navigation';
import Navigation from 'CommonUI/src/Utils/Navigation';
import ConfirmModal from 'CommonUI/src/Components/Modal/ConfirmModal';
import { ButtonStyleType } from 'CommonUI/src/Components/Button/Button';
import ProbeElement from '../../Components/Probe/Probe';
import ProbeElement from 'CommonUI/src/Components/Probe/Probe';
import Statusbubble from 'CommonUI/src/Components/StatusBubble/StatusBubble';
import { Green, Red } from 'Common/Types/BrandColors';
import OneUptimeDate from 'Common/Types/Date';

View File

@@ -743,7 +743,10 @@ app.use(
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<GlobalConfig, GlobalConfigServiceType>(GlobalConfig, GlobalConfigService).getRouter()
new BaseAPI<GlobalConfig, GlobalConfigServiceType>(
GlobalConfig,
GlobalConfigService
).getRouter()
);
app.use(

View File

@@ -32,14 +32,9 @@ import Port from 'Common/Types/Port';
update: [],
})
export default class GlobalConfig extends GlobalConfigModel {
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
@@ -56,21 +51,15 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public host?: string = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.Boolean,
title: 'Use HTTPS',
description:
'Is this server hosted on with SSL/TLS?',
description: 'Is this server hosted on with SSL/TLS?',
})
@Column({
type: ColumnType.Boolean,
@@ -79,23 +68,17 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public useHttps?: boolean = undefined;
// SMTP Settings.
// SMTP Settings.
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.Boolean,
title: 'Is SMTP Secure',
description:
'Is this SMTP server hosted with SSL/TLS?',
description: 'Is this SMTP server hosted with SSL/TLS?',
})
@Column({
type: ColumnType.Boolean,
@@ -104,21 +87,15 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public isSMTPSecure?: boolean = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: 'SMTP Username',
description:
'Username for your SMTP Server',
description: 'Username for your SMTP Server',
})
@Column({
type: ColumnType.ShortText,
@@ -128,21 +105,15 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public smtpUsername?: string = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: 'SMTP Password',
description:
'Password for your SMTP Server',
description: 'Password for your SMTP Server',
})
@Column({
type: ColumnType.ShortText,
@@ -152,45 +123,33 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public smtpPassword?: string = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.Number,
title: 'SMTP Port',
description:
'Port for your SMTP Server',
description: 'Port for your SMTP Server',
})
@Column({
type: ColumnType.Number,
nullable: true,
unique: true,
transformer: Port.getDatabaseTransformer()
transformer: Port.getDatabaseTransformer(),
})
public smtpPort?: Port = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: 'SMTP Host',
description:
'Host for your SMTP Server',
description: 'Host for your SMTP Server',
})
@Column({
type: ColumnType.ShortText,
@@ -200,46 +159,34 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public smtpHost?: string = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.Email,
title: 'SMTP From Email',
description:
'Which email should we send mail from?',
description: 'Which email should we send mail from?',
})
@Column({
type: ColumnType.Email,
length: ColumnLength.Email,
nullable: true,
unique: true,
transformer: Email.getDatabaseTransformer()
transformer: Email.getDatabaseTransformer(),
})
public smtpFromEmail?: Email = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: 'SMTP From Name',
description:
'Which name should we send emails from?',
description: 'Which name should we send emails from?',
})
@Column({
type: ColumnType.ShortText,
@@ -249,24 +196,17 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public smtpFromName?: string = undefined;
// Twilio config.
// Twilio config.
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: 'Twilio Account SID',
description:
'Account SID for your Twilio Account',
description: 'Account SID for your Twilio Account',
})
@Column({
type: ColumnType.ShortText,
@@ -276,21 +216,15 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public twilioAccountSID?: string = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.ShortText,
title: 'Twilio Auth Token',
description:
'Auth Token for your Twilio Account',
description: 'Auth Token for your Twilio Account',
})
@Column({
type: ColumnType.ShortText,
@@ -300,30 +234,22 @@ export default class GlobalConfig extends GlobalConfigModel {
})
public twilioAuthToken?: string = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
create: [],
read: [],
update: [],
})
@TableColumn({
type: TableColumnType.Phone,
title: 'Twilio Phone Number',
description:
'Phone Number for your Twilio account',
description: 'Phone Number for your Twilio account',
})
@Column({
type: ColumnType.Phone,
length: ColumnLength.Phone,
nullable: true,
unique: true,
transformer: Phone.getDatabaseTransformer()
transformer: Phone.getDatabaseTransformer(),
})
public twilioPhoneNumber?: Phone = undefined;
}

View File

@@ -238,7 +238,7 @@ export default [
PromoCode,
GlobalConfig
GlobalConfig,
];
export const AnalyticsModels: Array<typeof AnalyticsBaseModel> = [Log];

View File

@@ -14,10 +14,10 @@ export default class AddDefaultGlobalConfig extends DataMigrationBase {
const globalConfig: GlobalConfig = new GlobalConfig();
globalConfig.id = ObjectID.getZeroObjectID();
globalConfig.host = 'localhost';
globalConfig.useHttps = false;
globalConfig.useHttps = false;
await GlobalConfigService.create({
data: globalConfig,
data: globalConfig,
props: {
isRoot: true,
},

View File

@@ -16,7 +16,7 @@ const DataMigrations: Array<DataMigrationBase> = [
new MigrateToMeteredSubscription(),
new UpdateActiveMonitorCountToBillingProvider(),
new AddMonitoringDatesToMonitor(),
new AddDefaultGlobalConfig()
new AddDefaultGlobalConfig(),
];
export default DataMigrations;