mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 08:42:13 +02:00
Compare commits
394 Commits
7.0.4543
...
probe-queu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4c6793b29 | ||
|
|
c894b112e6 | ||
|
|
304baf1bb4 | ||
|
|
9adea6b1ba | ||
|
|
5498521e02 | ||
|
|
9e97c6ddbc | ||
|
|
63272e09f8 | ||
|
|
327c28afdc | ||
|
|
896020b93b | ||
|
|
15a68472b0 | ||
|
|
0210480d97 | ||
|
|
72fdc06687 | ||
|
|
3710b81b9a | ||
|
|
9fcb3dc2e0 | ||
|
|
43e2ccf51a | ||
|
|
48c3d8603a | ||
|
|
9cfc912161 | ||
|
|
29e3ee57ab | ||
|
|
be7e849822 | ||
|
|
59d76b601a | ||
|
|
b77ef336b8 | ||
|
|
7df21fe8e5 | ||
|
|
f39e1943c7 | ||
|
|
966a903646 | ||
|
|
1d9d37c6d1 | ||
|
|
7edcc4dbce | ||
|
|
0939294d22 | ||
|
|
dbcbfe5f79 | ||
|
|
a638972817 | ||
|
|
37c6310465 | ||
|
|
a7d38389fd | ||
|
|
2f55336db7 | ||
|
|
f99a15b95b | ||
|
|
de5bff2ffe | ||
|
|
cef2764499 | ||
|
|
a7014ac3ff | ||
|
|
fa31dc670c | ||
|
|
4c2a12cf31 | ||
|
|
b4115e1529 | ||
|
|
3883790c50 | ||
|
|
1702558d73 | ||
|
|
cacdbff50e | ||
|
|
0bc6b432a2 | ||
|
|
eaa09d4a13 | ||
|
|
08c85dd31c | ||
|
|
42e82b6fb7 | ||
|
|
463a20f342 | ||
|
|
1b8a7e3261 | ||
|
|
8b27dd1f26 | ||
|
|
17c72f65e3 | ||
|
|
5eee900fd3 | ||
|
|
0a6cdd11af | ||
|
|
8514b6b82e | ||
|
|
dfa8f6cd24 | ||
|
|
61614227e1 | ||
|
|
f3d20eb544 | ||
|
|
a11ff57fda | ||
|
|
deb635bc80 | ||
|
|
c707830811 | ||
|
|
24ada68d1e | ||
|
|
ca23234ba9 | ||
|
|
ea40a955e9 | ||
|
|
a46ee07d70 | ||
|
|
5c5bab408d | ||
|
|
540d632baf | ||
|
|
74718017ad | ||
|
|
d16897db1b | ||
|
|
be3fc6f077 | ||
|
|
b7b577517c | ||
|
|
ccf7a96e43 | ||
|
|
892f3c052a | ||
|
|
00833a06f4 | ||
|
|
472adf610a | ||
|
|
976c36de9a | ||
|
|
6026c9c9af | ||
|
|
791aa1421b | ||
|
|
79dbc94f82 | ||
|
|
ded41fc7ec | ||
|
|
581c374745 | ||
|
|
64c0c8b4cb | ||
|
|
7d2241ba98 | ||
|
|
30bada5b7a | ||
|
|
61bfb37747 | ||
|
|
4686aa941a | ||
|
|
3c065c76b0 | ||
|
|
5dccd03ed4 | ||
|
|
a395a95997 | ||
|
|
89082b1232 | ||
|
|
7cb33de450 | ||
|
|
353ac875fb | ||
|
|
d6560fdb32 | ||
|
|
5115e21a7a | ||
|
|
0e6119ddce | ||
|
|
b842a49cfb | ||
|
|
9737e50467 | ||
|
|
91beb6091d | ||
|
|
68e610aa9f | ||
|
|
d673ef3a01 | ||
|
|
6dff8f07bf | ||
|
|
4ca836c91f | ||
|
|
d59ba73993 | ||
|
|
e878855b31 | ||
|
|
8f95ae65f6 | ||
|
|
995b93f525 | ||
|
|
fc3c11b12d | ||
|
|
d0ce225b66 | ||
|
|
b486b59598 | ||
|
|
4d7135fb11 | ||
|
|
0c4464ed87 | ||
|
|
d705ea6896 | ||
|
|
ac146df9e8 | ||
|
|
3ce7d54eef | ||
|
|
418c89c15b | ||
|
|
80144814d1 | ||
|
|
f3223e397b | ||
|
|
fce5e18fba | ||
|
|
cdd60c1d6b | ||
|
|
cb35a0d420 | ||
|
|
b198d4d87d | ||
|
|
285a5355a7 | ||
|
|
777093d2e1 | ||
|
|
0444b09ad5 | ||
|
|
7be9c4b1e7 | ||
|
|
79910b6c0b | ||
|
|
0686dea83c | ||
|
|
e1e27c4e94 | ||
|
|
6fe14fbed3 | ||
|
|
9ef248f71e | ||
|
|
e243a76dab | ||
|
|
71466089a4 | ||
|
|
31e6172af4 | ||
|
|
7a228f76e4 | ||
|
|
40d473d195 | ||
|
|
f2f5b757eb | ||
|
|
1d4d93ceec | ||
|
|
40819562f7 | ||
|
|
066ad4a52d | ||
|
|
a109ae33e0 | ||
|
|
19ac60d8db | ||
|
|
7557103cc0 | ||
|
|
d1bd8c09d1 | ||
|
|
861c1782fc | ||
|
|
f937749c7e | ||
|
|
6752ba8b63 | ||
|
|
dce9f2fe78 | ||
|
|
d18c3af5ac | ||
|
|
d48f864512 | ||
|
|
0976b2700c | ||
|
|
58990d9991 | ||
|
|
934b08d643 | ||
|
|
b832613fb2 | ||
|
|
3faa2fe302 | ||
|
|
a1fe600863 | ||
|
|
74af666d70 | ||
|
|
4707b4b4dd | ||
|
|
78d34542b6 | ||
|
|
141280ad0e | ||
|
|
92f978df20 | ||
|
|
e3db66734f | ||
|
|
618dcbdcce | ||
|
|
af66709363 | ||
|
|
5ebe067efd | ||
|
|
a59c98d7e6 | ||
|
|
5ff1d15b36 | ||
|
|
f4cdefc4f9 | ||
|
|
8b11be85bf | ||
|
|
6e2416910e | ||
|
|
0cd0e174bf | ||
|
|
b7153ed283 | ||
|
|
34718f6fa7 | ||
|
|
ed69c5de39 | ||
|
|
5f9f741b82 | ||
|
|
a427a82327 | ||
|
|
6244ff4ebc | ||
|
|
9007ed5ddc | ||
|
|
108d1fdfcc | ||
|
|
7678cc9d77 | ||
|
|
708ea2c977 | ||
|
|
0ebfb294ff | ||
|
|
d6d61a61fd | ||
|
|
46a0e54771 | ||
|
|
71807da876 | ||
|
|
d7b45106d8 | ||
|
|
1a39c2f6c5 | ||
|
|
7b2041f6a4 | ||
|
|
31cfba9ab8 | ||
|
|
1ead9679c3 | ||
|
|
01be21d0ed | ||
|
|
c8986fb314 | ||
|
|
951fcbe474 | ||
|
|
7483ff2c2f | ||
|
|
14fc484e37 | ||
|
|
bd2da4358b | ||
|
|
78d43e1a1c | ||
|
|
a84a6a0c55 | ||
|
|
66343e6920 | ||
|
|
6a7a8ad8d9 | ||
|
|
b8faa692cb | ||
|
|
ca99f452ac | ||
|
|
cd8d851366 | ||
|
|
16bed1861c | ||
|
|
c0909c68c8 | ||
|
|
97654f61a2 | ||
|
|
faa4d8372c | ||
|
|
da4741fcf4 | ||
|
|
3c420b2114 | ||
|
|
9c5a649157 | ||
|
|
4908e9cd1d | ||
|
|
f552115fd5 | ||
|
|
a96fc24562 | ||
|
|
a54d44df01 | ||
|
|
7afa17cd8d | ||
|
|
2d15d85310 | ||
|
|
1a577cf406 | ||
|
|
3869725742 | ||
|
|
2b286e76f1 | ||
|
|
3a791cec3b | ||
|
|
0e4557dba7 | ||
|
|
c594d390cb | ||
|
|
8a66434af9 | ||
|
|
c8ddba76f7 | ||
|
|
4831ed0535 | ||
|
|
7e4f1d6b55 | ||
|
|
1a254ee8cc | ||
|
|
429a1497ec | ||
|
|
e9bff64ea1 | ||
|
|
603f803dd5 | ||
|
|
0df55c0b6f | ||
|
|
a22e42cf8d | ||
|
|
2e8340ee76 | ||
|
|
72429923ed | ||
|
|
ca5eccfe83 | ||
|
|
3b4f3e5f1e | ||
|
|
0a65c72b80 | ||
|
|
42a468720f | ||
|
|
267bbad661 | ||
|
|
6542bf7564 | ||
|
|
ec746ba507 | ||
|
|
5aacfd05a9 | ||
|
|
2840a3560b | ||
|
|
0f688350dc | ||
|
|
39b572da3f | ||
|
|
5423293fbc | ||
|
|
009ef21d16 | ||
|
|
793a33f873 | ||
|
|
bafbf3fc01 | ||
|
|
4586b27039 | ||
|
|
9f65f31d6c | ||
|
|
5a9d351d39 | ||
|
|
6dc432b7f3 | ||
|
|
1e04f37727 | ||
|
|
be34930cd5 | ||
|
|
c8b053d17c | ||
|
|
ced4d0446c | ||
|
|
357f76ae5b | ||
|
|
7f11735f79 | ||
|
|
4ad1918b1d | ||
|
|
122b0d6be7 | ||
|
|
3116100f1a | ||
|
|
38194331e6 | ||
|
|
d6ebd65417 | ||
|
|
4c467d0e3b | ||
|
|
49efec2a77 | ||
|
|
d73b6c6205 | ||
|
|
8db9c69e1e | ||
|
|
00e50f023f | ||
|
|
f4db88e874 | ||
|
|
255149e3d5 | ||
|
|
f1b4a396ec | ||
|
|
82b62d32fd | ||
|
|
161b80c19a | ||
|
|
ff58beb50e | ||
|
|
63236366ee | ||
|
|
cbdc3186af | ||
|
|
ab0936067c | ||
|
|
24c083cdb8 | ||
|
|
6ce945ac2c | ||
|
|
1c9e9b37d3 | ||
|
|
83c740d8cb | ||
|
|
84819c73ff | ||
|
|
ce166f2f35 | ||
|
|
11b54365f0 | ||
|
|
432debc014 | ||
|
|
d9f87c4103 | ||
|
|
680e33ba43 | ||
|
|
22162425fb | ||
|
|
93d935d117 | ||
|
|
48d9964c70 | ||
|
|
d2921e3516 | ||
|
|
5c7e5a1eda | ||
|
|
f62a01594d | ||
|
|
99de9fbd3d | ||
|
|
7a0f31e10a | ||
|
|
22cee30cdb | ||
|
|
5524d9d147 | ||
|
|
9fb4f00460 | ||
|
|
7e761cc6dd | ||
|
|
bcfbed0249 | ||
|
|
208c7406f9 | ||
|
|
2a41fec3cd | ||
|
|
73ea4bbb7c | ||
|
|
1b657b4758 | ||
|
|
7027739a81 | ||
|
|
3491869196 | ||
|
|
f6e106fb65 | ||
|
|
fd96b0f287 | ||
|
|
04ee339d58 | ||
|
|
2a74183de5 | ||
|
|
747d46eb83 | ||
|
|
00b0be251e | ||
|
|
1cc057d256 | ||
|
|
907d3308d5 | ||
|
|
1e254e32fd | ||
|
|
f2de3cc8a8 | ||
|
|
e6c33c8e6d | ||
|
|
74c42ab0fe | ||
|
|
31434d7eb3 | ||
|
|
9b9d6cf6a8 | ||
|
|
abb793b2ae | ||
|
|
3119b8cfc2 | ||
|
|
eed5ce6ec9 | ||
|
|
46558d4a77 | ||
|
|
cef6638b2c | ||
|
|
031750d573 | ||
|
|
4287632371 | ||
|
|
5c464ae137 | ||
|
|
cf6ee298cc | ||
|
|
8718e58dcb | ||
|
|
df4bc5ce12 | ||
|
|
fccfb5b026 | ||
|
|
793de2623a | ||
|
|
05f2096e3e | ||
|
|
d291cdad26 | ||
|
|
84fef8e48f | ||
|
|
de62d40d6e | ||
|
|
98bf1ef155 | ||
|
|
4939305c08 | ||
|
|
cd77106939 | ||
|
|
678a2ac498 | ||
|
|
0b3765594f | ||
|
|
9f77e8d82d | ||
|
|
78fca73b8a | ||
|
|
82e2bc75bf | ||
|
|
85de170031 | ||
|
|
338a2dc2cc | ||
|
|
d400271f3c | ||
|
|
8c735e1500 | ||
|
|
d4b0ac7b9c | ||
|
|
8edcdd37e3 | ||
|
|
ed65a477e4 | ||
|
|
98e3386d22 | ||
|
|
c2b4f1d117 | ||
|
|
fe879d86ce | ||
|
|
9e63a4cbf5 | ||
|
|
6c5ba10a52 | ||
|
|
9c9751c2c7 | ||
|
|
1b70517463 | ||
|
|
38f79900cc | ||
|
|
9fc8d679d8 | ||
|
|
83838da879 | ||
|
|
4e6e7cf354 | ||
|
|
dfc4e2e7f8 | ||
|
|
8f9c463d85 | ||
|
|
82af0bee58 | ||
|
|
babf818963 | ||
|
|
b4477e04ef | ||
|
|
f0457df102 | ||
|
|
73a1997f4c | ||
|
|
e4e7b7c7d8 | ||
|
|
aa7bd3140c | ||
|
|
095ad5dbf4 | ||
|
|
f8c8f26cab | ||
|
|
a923b0f885 | ||
|
|
d352610ca7 | ||
|
|
23c57a1483 | ||
|
|
d3106e4ac8 | ||
|
|
a0acf8cac2 | ||
|
|
b29df21b4d | ||
|
|
e1f52ebd26 | ||
|
|
0248ae5ec6 | ||
|
|
064ff68147 | ||
|
|
5794e40fd1 | ||
|
|
51faf12723 | ||
|
|
1c658651ac | ||
|
|
482c6d3e0b | ||
|
|
441ab82acf | ||
|
|
7d18b81ea5 | ||
|
|
a8c3ca5f01 | ||
|
|
1d57657b72 | ||
|
|
a4bb6744f4 | ||
|
|
4d3ef70765 | ||
|
|
6f71a67adf | ||
|
|
a701f5eff0 | ||
|
|
b7ea97c246 |
16
.github/workflows/build.yml
vendored
16
.github/workflows/build.yml
vendored
@@ -209,22 +209,6 @@ jobs:
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Dashboard/Dockerfile .
|
||||
|
||||
docker-build-haraka:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Preinstall
|
||||
run: npm run prerun
|
||||
|
||||
# build images
|
||||
- name: build docker image
|
||||
run: sudo docker build -f ./Haraka/Dockerfile .
|
||||
|
||||
|
||||
docker-build-probe:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
|
||||
14
.github/workflows/compile.yml
vendored
14
.github/workflows/compile.yml
vendored
@@ -290,4 +290,16 @@ jobs:
|
||||
with:
|
||||
node-version: latest
|
||||
- run: cd Common && npm install
|
||||
- run: cd TestServer && npm install && npm run compile && npm run dep-check
|
||||
- run: cd TestServer && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-mcp:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
- run: cd Common && npm install
|
||||
- run: cd MCP && npm install && npm run compile && npm run dep-check
|
||||
201
.github/workflows/release.yml
vendored
201
.github/workflows/release.yml
vendored
@@ -68,6 +68,142 @@ jobs:
|
||||
git commit -m "Helm Chart Release 7.0.${{needs.generate-build-number.outputs.build_number}}"
|
||||
git push origin master
|
||||
|
||||
publish-mcp-server:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [generate-build-number, publish-npm-packages]
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{ github.run_number }}
|
||||
NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
|
||||
permissions:
|
||||
contents: write # For creating releases
|
||||
packages: write # For publishing packages
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Full history for changelog generation
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install Common dependencies
|
||||
run: cd Common && npm install
|
||||
|
||||
- name: Install root dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Install Script dependencies
|
||||
run: cd Scripts && npm install
|
||||
|
||||
- name: Determine version
|
||||
id: version
|
||||
run: |
|
||||
VERSION="7.0.${{needs.generate-build-number.outputs.build_number}}"
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Publishing MCP server version: $VERSION"
|
||||
|
||||
- name: Verify MCP server directory
|
||||
run: |
|
||||
MCP_DIR="./MCP"
|
||||
|
||||
if [ ! -d "$MCP_DIR" ]; then
|
||||
echo "❌ MCP server directory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ MCP server directory found"
|
||||
echo "📊 Source files:"
|
||||
find "$MCP_DIR" -type f -name "*.ts" -o -name "*.js" -o -name "*.json" | wc -l
|
||||
echo "📁 Directory structure:"
|
||||
ls -la "$MCP_DIR"
|
||||
|
||||
- name: Setup npm authentication
|
||||
run: |
|
||||
# Clean up any existing npm configuration that might cause warnings
|
||||
rm -f ~/.npmrc
|
||||
# Create npmrc file with authentication
|
||||
touch ~/.npmrc
|
||||
echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" >> ~/.npmrc
|
||||
echo "//registry.npmjs.org/:email=npm@oneuptime.com" >> ~/.npmrc
|
||||
echo "✅ npm authentication configured"
|
||||
|
||||
- name: Update package version
|
||||
run: |
|
||||
cd MCP
|
||||
npm version ${{ steps.version.outputs.version }} --no-git-tag-version
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd MCP
|
||||
npm update @oneuptime/common
|
||||
npm install
|
||||
|
||||
- name: Build MCP server
|
||||
run: |
|
||||
cd MCP
|
||||
npm run build
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd MCP
|
||||
npm test || echo "No tests found or tests failed, continuing..."
|
||||
|
||||
- name: Verify package before publish
|
||||
run: |
|
||||
cd MCP
|
||||
echo "📦 Package information:"
|
||||
npm publish --dry-run
|
||||
echo "📋 Package.json bin configuration:"
|
||||
cat package.json | grep -A 5 -B 5 '"bin"'
|
||||
echo "📁 Build directory contents:"
|
||||
ls -la build/
|
||||
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
cd MCP
|
||||
npm publish --access public
|
||||
echo "✅ Published @oneuptime/mcp-server@${{ steps.version.outputs.version }} to npm"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker images
|
||||
run: |
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--file ./MCP/Dockerfile.tpl \
|
||||
--tag oneuptime/mcp-server:${{ steps.version.outputs.version }} \
|
||||
--tag oneuptime/mcp-server:release \
|
||||
--tag ghcr.io/oneuptime/mcp-server:${{ steps.version.outputs.version }} \
|
||||
--tag ghcr.io/oneuptime/mcp-server:release \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{ steps.version.outputs.version }} \
|
||||
--push .
|
||||
echo "✅ Pushed Docker images to Docker Hub and GitHub Container Registry"
|
||||
|
||||
- name: Upload MCP server artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: mcp-server-${{ steps.version.outputs.version }}
|
||||
path: ./MCP/
|
||||
retention-days: 90
|
||||
|
||||
nginx-docker-image-deploy:
|
||||
needs: [generate-build-number]
|
||||
runs-on: ubuntu-latest
|
||||
@@ -917,67 +1053,6 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
|
||||
haraka-docker-image-deploy:
|
||||
needs: [generate-build-number]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/haraka
|
||||
ghcr.io/oneuptime/haraka
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy haraka.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Haraka/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
admin-dashboard-docker-image-deploy:
|
||||
needs: [generate-build-number]
|
||||
runs-on: ubuntu-latest
|
||||
@@ -1703,7 +1778,7 @@ jobs:
|
||||
|
||||
test-e2e-release-saas:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [open-telemetry-ingest-docker-image-deploy, copilot-docker-image-deploy, fluent-ingest-docker-image-deploy, docs-docker-image-deploy, api-reference-docker-image-deploy, workflow-docker-image-deploy, llm-docker-image-deploy, accounts-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, dashboard-docker-image-deploy, haraka-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, worker-docker-image-deploy, otel-collector-docker-image-deploy, probe-docker-image-deploy, status-page-docker-image-deploy, test-docker-image-deploy, test-server-docker-image-deploy, publish-npm-packages, e2e-docker-image-deploy, helm-chart-deploy, generate-build-number, nginx-docker-image-deploy, incoming-request-ingest-docker-image-deploy]
|
||||
needs: [open-telemetry-ingest-docker-image-deploy, copilot-docker-image-deploy, fluent-ingest-docker-image-deploy, docs-docker-image-deploy, api-reference-docker-image-deploy, workflow-docker-image-deploy, llm-docker-image-deploy, accounts-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, dashboard-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, worker-docker-image-deploy, otel-collector-docker-image-deploy, probe-docker-image-deploy, status-page-docker-image-deploy, test-docker-image-deploy, test-server-docker-image-deploy, publish-npm-packages, e2e-docker-image-deploy, helm-chart-deploy, generate-build-number, nginx-docker-image-deploy, incoming-request-ingest-docker-image-deploy]
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
@@ -1756,7 +1831,7 @@ jobs:
|
||||
test-e2e-release-self-hosted:
|
||||
runs-on: ubuntu-latest
|
||||
# After all the jobs runs
|
||||
needs: [open-telemetry-ingest-docker-image-deploy, copilot-docker-image-deploy, incoming-request-ingest-docker-image-deploy, fluent-ingest-docker-image-deploy, docs-docker-image-deploy, api-reference-docker-image-deploy, workflow-docker-image-deploy, llm-docker-image-deploy, accounts-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, dashboard-docker-image-deploy, haraka-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, worker-docker-image-deploy, otel-collector-docker-image-deploy, probe-docker-image-deploy, status-page-docker-image-deploy, test-docker-image-deploy, test-server-docker-image-deploy, publish-npm-packages, e2e-docker-image-deploy, helm-chart-deploy, generate-build-number, nginx-docker-image-deploy]
|
||||
needs: [open-telemetry-ingest-docker-image-deploy, publish-mcp-server, copilot-docker-image-deploy, incoming-request-ingest-docker-image-deploy, fluent-ingest-docker-image-deploy, docs-docker-image-deploy, api-reference-docker-image-deploy, workflow-docker-image-deploy, llm-docker-image-deploy, accounts-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, dashboard-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, worker-docker-image-deploy, otel-collector-docker-image-deploy, probe-docker-image-deploy, status-page-docker-image-deploy, test-docker-image-deploy, test-server-docker-image-deploy, publish-npm-packages, e2e-docker-image-deploy, helm-chart-deploy, generate-build-number, nginx-docker-image-deploy]
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
|
||||
175
.github/workflows/test-release.yaml
vendored
175
.github/workflows/test-release.yaml
vendored
@@ -84,6 +84,118 @@ jobs:
|
||||
- name: Generate Terraform provider
|
||||
run: npm run publish-terraform-provider -- --version "${{ steps.version.outputs.version }}" --github-token "${{ secrets.SIMLARSEN_GITHUB_PAT }}" --github-repo-deploy-key "${{ secrets.TERRAFORM_PROVIDER_GITHUB_REPO_DEPLOY_KEY }}" --test-release
|
||||
|
||||
publish-mcp-server:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [generate-build-number]
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{ github.run_number }}
|
||||
permissions:
|
||||
contents: write # For creating releases
|
||||
packages: write # For publishing packages
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Full history for changelog generation
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
cache: 'npm'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install Common dependencies
|
||||
run: cd Common && npm install
|
||||
|
||||
- name: Install root dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Install Script dependencies
|
||||
run: cd Scripts && npm install
|
||||
|
||||
- name: Determine version
|
||||
id: version
|
||||
run: |
|
||||
VERSION="7.0.${{needs.generate-build-number.outputs.build_number}}-test"
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Publishing MCP server version: $VERSION"
|
||||
|
||||
- name: Verify MCP server directory
|
||||
run: |
|
||||
MCP_DIR="./MCP"
|
||||
|
||||
if [ ! -d "$MCP_DIR" ]; then
|
||||
echo "❌ MCP server directory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ MCP server directory found"
|
||||
echo "📊 Source files:"
|
||||
find "$MCP_DIR" -type f -name "*.ts" -o -name "*.js" -o -name "*.json" | wc -l
|
||||
echo "📁 Directory structure:"
|
||||
ls -la "$MCP_DIR"
|
||||
|
||||
- name: Update package version
|
||||
run: |
|
||||
cd MCP
|
||||
npm version ${{ steps.version.outputs.version }} --no-git-tag-version
|
||||
|
||||
- name: Install dependencies and build
|
||||
run: |
|
||||
cd MCP
|
||||
npm update @oneuptime/common
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd MCP
|
||||
npm test || echo "No tests found or tests failed, continuing..."
|
||||
|
||||
- name: Publish to npm (dry run for test releases)
|
||||
run: |
|
||||
cd MCP
|
||||
npm pack --dry-run
|
||||
echo "✅ Dry run completed successfully for test release"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker images (test)
|
||||
run: |
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--file ./MCP/Dockerfile.tpl \
|
||||
--tag oneuptime/mcp-server:${{ steps.version.outputs.version }} \
|
||||
--tag oneuptime/mcp-server:test \
|
||||
--tag ghcr.io/oneuptime/mcp-server:${{ steps.version.outputs.version }} \
|
||||
--tag ghcr.io/oneuptime/mcp-server:test \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{ steps.version.outputs.version }} \
|
||||
--push .
|
||||
echo "✅ Pushed test Docker images to Docker Hub and GitHub Container Registry"
|
||||
|
||||
- name: Upload MCP server artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: mcp-server-${{ steps.version.outputs.version }}
|
||||
path: ./MCP/
|
||||
retention-days: 90
|
||||
|
||||
|
||||
|
||||
llm-docker-image-deploy:
|
||||
@@ -1035,67 +1147,6 @@ jobs:
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
haraka-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/haraka
|
||||
ghcr.io/oneuptime/haraka
|
||||
tags: |
|
||||
type=raw,value=test,enable=true
|
||||
type=semver,value=7.0.${{needs.generate-build-number.outputs.build_number}}-test,pattern={{version}},enable=true
|
||||
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
run: npm run prerun
|
||||
|
||||
# Build and deploy haraka.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: ./Haraka/Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_SHA=${{ github.sha }}
|
||||
APP_VERSION=7.0.${{needs.generate-build-number.outputs.build_number}}
|
||||
|
||||
dashboard-docker-image-deploy:
|
||||
needs: generate-build-number
|
||||
runs-on: ubuntu-latest
|
||||
@@ -1657,7 +1708,7 @@ jobs:
|
||||
|
||||
test-helm-chart:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [infrastructure-agent-deploy, llm-docker-image-deploy, publish-terraform-provider, open-telemetry-ingest-docker-image-deploy, copilot-docker-image-deploy, docs-docker-image-deploy, worker-docker-image-deploy, workflow-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, api-reference-docker-image-deploy, test-server-docker-image-deploy, test-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, probe-docker-image-deploy, haraka-docker-image-deploy, dashboard-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, accounts-docker-image-deploy, otel-collector-docker-image-deploy, status-page-docker-image-deploy, nginx-docker-image-deploy, e2e-docker-image-deploy, fluent-ingest-docker-image-deploy, incoming-request-ingest-docker-image-deploy]
|
||||
needs: [infrastructure-agent-deploy, publish-mcp-server, llm-docker-image-deploy, publish-terraform-provider, open-telemetry-ingest-docker-image-deploy, copilot-docker-image-deploy, docs-docker-image-deploy, worker-docker-image-deploy, workflow-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, api-reference-docker-image-deploy, test-server-docker-image-deploy, test-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, probe-docker-image-deploy, dashboard-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, accounts-docker-image-deploy, otel-collector-docker-image-deploy, status-page-docker-image-deploy, nginx-docker-image-deploy, e2e-docker-image-deploy, fluent-ingest-docker-image-deploy, incoming-request-ingest-docker-image-deploy]
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
|
||||
21
.github/workflows/test.mcp.yaml
vendored
Normal file
21
.github/workflows/test.mcp.yaml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: MCP Server Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'hotfix-*' # excludes hotfix branches
|
||||
- 'release'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
- run: cd Common && npm install
|
||||
- run: cd MCP && npm install && npm run test
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -86,9 +86,6 @@ Backups/*.tar
|
||||
|
||||
.env
|
||||
|
||||
Haraka/dkim/keys/private_base64.txt
|
||||
Haraka/dkim/keys/public_base64.txt
|
||||
|
||||
.eslintcache
|
||||
|
||||
HelmChart/Values/*.values.yaml
|
||||
@@ -123,4 +120,10 @@ Terraform/**
|
||||
|
||||
TerraformTest/**
|
||||
|
||||
terraform-provider-example/**
|
||||
terraform-provider-example/**
|
||||
|
||||
# MCP Server
|
||||
MCP/build/
|
||||
MCP/.env
|
||||
MCP/node_modules
|
||||
Dashboard/public/sw.js
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"query": {
|
||||
"name": "Hello",
|
||||
// other filters
|
||||
"age": {
|
||||
"_type": "EqualTo",
|
||||
value: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
11
APIReference/CodeExamples/DataTypes/Includes.md
Normal file
11
APIReference/CodeExamples/DataTypes/Includes.md
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"query": {
|
||||
"labels": {
|
||||
"_type": "Includes",
|
||||
"value": [
|
||||
"aaa00000-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
|
||||
"bbb00000-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,8 @@ CMD [ "npm", "run", "dev" ]
|
||||
COPY ./APIReference /usr/src/app
|
||||
# Bundle app source
|
||||
RUN npm run compile
|
||||
# Set permission to write logs and cache in case container run as non root
|
||||
RUN chown -R 1000:1000 "/tmp/npm" && chmod -R 2777 "/tmp/npm"
|
||||
#Run the app
|
||||
CMD [ "npm", "start" ]
|
||||
{{ end }}
|
||||
|
||||
@@ -88,6 +88,16 @@ export default class ServiceHandler {
|
||||
},
|
||||
);
|
||||
|
||||
pageData.includesCode = await LocalCache.getOrSetString(
|
||||
"data-type",
|
||||
"includes",
|
||||
async () => {
|
||||
return await LocalFile.read(
|
||||
`${CodeExamplesPath}/DataTypes/Includes.md`,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
pageData.lessThanOrNullCode = await LocalCache.getOrSetString(
|
||||
"data-type",
|
||||
"less-than-or-equal",
|
||||
|
||||
77
APIReference/package-lock.json
generated
77
APIReference/package-lock.json
generated
@@ -1,17 +1,16 @@
|
||||
{
|
||||
"name": "@oneuptime/app",
|
||||
"name": "@oneuptime/api-reference",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@oneuptime/app",
|
||||
"name": "@oneuptime/api-reference",
|
||||
"version": "1.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"Common": "file:../Common",
|
||||
"ejs": "^3.1.9",
|
||||
"handlebars": "^4.7.8",
|
||||
"ts-node": "^10.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -26,8 +25,9 @@
|
||||
"version": "1.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@asteasolutions/zod-to-openapi": "^7.3.2",
|
||||
"@bull-board/express": "^5.21.4",
|
||||
"@clickhouse/client": "^0.2.10",
|
||||
"@clickhouse/client": "^1.10.1",
|
||||
"@elastic/elasticsearch": "^8.12.1",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
@@ -55,18 +55,19 @@
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/web-push": "^3.6.4",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.7.2",
|
||||
"bullmq": "^5.3.3",
|
||||
"Common": "file:../Common",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"cron-parser": "^4.8.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dotenv": "^16.4.4",
|
||||
"ejs": "^3.1.10",
|
||||
"express": "^4.19.2",
|
||||
"esbuild": "^0.25.5",
|
||||
"express": "^4.21.1",
|
||||
"formik": "^2.4.6",
|
||||
"history": "^5.3.0",
|
||||
"ioredis": "^5.3.2",
|
||||
@@ -74,7 +75,6 @@
|
||||
"json5": "^2.2.3",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^12.0.2",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
@@ -82,6 +82,7 @@
|
||||
"nodemailer": "^6.9.10",
|
||||
"otpauth": "^9.3.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright": "^1.50.0",
|
||||
"posthog-js": "^1.139.6",
|
||||
"prop-types": "^15.8.1",
|
||||
"qrcode": "^1.5.3",
|
||||
@@ -104,6 +105,7 @@
|
||||
"redis-semaphore": "^5.5.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"slackify-markdown": "^4.4.0",
|
||||
"slugify": "^1.6.5",
|
||||
"socket.io": "^4.7.4",
|
||||
"socket.io-client": "^4.7.5",
|
||||
@@ -113,9 +115,11 @@
|
||||
"twilio": "^4.22.0",
|
||||
"typeorm": "^0.3.20",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"universal-cookie": "^4.0.4",
|
||||
"universal-cookie": "^7.2.1",
|
||||
"use-async-effect": "^2.2.6",
|
||||
"uuid": "^8.3.2"
|
||||
"uuid": "^8.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"zod": "^3.25.30"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.2",
|
||||
@@ -129,7 +133,6 @@
|
||||
"@types/jest": "^28.1.4",
|
||||
"@types/json2csv": "^5.0.3",
|
||||
"@types/jsonwebtoken": "^8.5.9",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/node": "^17.0.45",
|
||||
"@types/node-cron": "^3.0.7",
|
||||
"@types/nodemailer": "^6.4.7",
|
||||
@@ -143,6 +146,7 @@
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jest-mock-extended": "^3.0.5",
|
||||
"react-test-renderer": "^18.2.0",
|
||||
"sass": "^1.89.2",
|
||||
"ts-jest": "^28.0.5"
|
||||
}
|
||||
},
|
||||
@@ -2378,26 +2382,6 @@
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/handlebars": {
|
||||
"version": "4.7.8",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
|
||||
"integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5",
|
||||
"neo-async": "^2.6.2",
|
||||
"source-map": "^0.6.1",
|
||||
"wordwrap": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"handlebars": "bin/handlebars"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.7"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"uglify-js": "^3.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@@ -3445,14 +3429,6 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
@@ -3465,11 +3441,6 @@
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/neo-async": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
|
||||
},
|
||||
"node_modules/node-int64": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
||||
@@ -3961,6 +3932,7 @@
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -4243,18 +4215,6 @@
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/uglify-js": {
|
||||
"version": "3.17.4",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
|
||||
"integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"uglifyjs": "bin/uglifyjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undefsafe": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
||||
@@ -4340,11 +4300,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of Equal To Query</p>
|
||||
<p>Here is an example of an Equal To Query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -153,7 +153,7 @@
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of Not Equal To Query</p>
|
||||
<p>Here is an example of a Not Equal To Query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -191,7 +191,7 @@
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of is null query</p>
|
||||
<p>Here is an example of an is null query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -229,7 +229,7 @@
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of is not null query</p>
|
||||
<p>Here is an example of an is not null query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -266,7 +266,7 @@
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of greater than query</p>
|
||||
<p>Here is an example of a greater than query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -304,7 +304,7 @@
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of greater or equal than query</p>
|
||||
<p>Here is an example of a greater than or equal query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -342,7 +342,7 @@
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of less than query</p>
|
||||
<p>Here is an example of a less than query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -380,7 +380,7 @@
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of less or equal than query</p>
|
||||
<p>Here is an example of a less than or equal query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
@@ -395,5 +395,44 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 id="example-using-cursors" class="scroll-mt-24">
|
||||
Inlcudes
|
||||
</h3>
|
||||
|
||||
<div class="grid grid-cols-1 items-start gap-x-16 gap-y-10 xl:max-w-none xl:grid-cols-2">
|
||||
<div class="[&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>
|
||||
Includes will get objects that match any of the values in the array. It is used to
|
||||
filter objects that have a field that matches any of the values in the array. For example, if you
|
||||
want to get all objects that have a label with ID `aaa00000-aaaa-aaaa-aaaa-aaaaaaaaaaaa` or
|
||||
`bbb00000-bbbb-bbbb-bbbb-bbbbbbbbbbbb`, you can use the `includes` query type.
|
||||
</p>
|
||||
|
||||
<div class="my-6">
|
||||
<ul role="list"
|
||||
class="m-0 max-w-[calc(theme(maxWidth.lg)-theme(spacing.8))] list-none divide-y divide-zinc-900/5 p-0 ">
|
||||
<li class="m-0 px-0 py-4 first:pt-0 last:pb-0">
|
||||
<dl class="m-0 flex flex-wrap items-center gap-x-3 gap-y-2">
|
||||
<dt class="sr-only">Query</dt>
|
||||
<dd><code class="inline-code">query</code></dd>
|
||||
<dt class="sr-only">Type</dt>
|
||||
<dd class="font-mono text-xs text-zinc-400 ">Query</dd>
|
||||
<dt class="sr-only">Description</dt>
|
||||
<dd class="w-full flex-none [&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>Here is an example of a less than or equal query</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="[&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<%- include('../partials/code', {title: "Example Not EqualTo Request Body" , requestUrl: "" , requestType: "" ,
|
||||
code: pageData.includesCode }) -%>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
@@ -13,7 +13,7 @@
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 items-start gap-x-16 gap-y-10 xl:max-w-none xl:grid-cols-2">
|
||||
<div class="[&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<p>In this example, we request the list fo monitors. As a result, we get a list of three monitors and can
|
||||
<p>In this example, we request the list of monitors. As a result, we get a list of three monitors and can
|
||||
tell by the <code class="inline-code">count</code> attribute that we have reached the end of the
|
||||
result set</p>
|
||||
<h2 id="example-using-cursors" class="scroll-mt-24">
|
||||
|
||||
@@ -83,6 +83,8 @@ COPY ./Accounts /usr/src/app
|
||||
# Bundle app source
|
||||
|
||||
RUN npm run build
|
||||
# Set permission to write logs and cache in case container run as non root
|
||||
RUN chown -R 1000:1000 "/tmp/npm" && chmod -R 2777 "/tmp/npm"
|
||||
#Run the app
|
||||
CMD [ "npm", "start" ]
|
||||
{{ end }}
|
||||
|
||||
4
Accounts/package-lock.json
generated
4
Accounts/package-lock.json
generated
@@ -59,6 +59,7 @@
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/web-push": "^3.6.4",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.7.2",
|
||||
@@ -78,7 +79,6 @@
|
||||
"json5": "^2.2.3",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^12.0.2",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
@@ -122,6 +122,7 @@
|
||||
"universal-cookie": "^7.2.1",
|
||||
"use-async-effect": "^2.2.6",
|
||||
"uuid": "^8.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"zod": "^3.25.30"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -136,7 +137,6 @@
|
||||
"@types/jest": "^28.1.4",
|
||||
"@types/json2csv": "^5.0.3",
|
||||
"@types/jsonwebtoken": "^8.5.9",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/node": "^17.0.45",
|
||||
"@types/node-cron": "^3.0.7",
|
||||
"@types/nodemailer": "^6.4.7",
|
||||
|
||||
@@ -79,6 +79,8 @@ CMD [ "npm", "run", "dev" ]
|
||||
COPY ./AdminDashboard /usr/src/app
|
||||
# Bundle app source
|
||||
RUN npm run build
|
||||
# Set permission to write logs and cache in case container run as non root
|
||||
RUN chown -R 1000:1000 "/tmp/npm" && chmod -R 2777 "/tmp/npm"
|
||||
#Run the app
|
||||
CMD [ "npm", "start" ]
|
||||
{{ end }}
|
||||
|
||||
4
AdminDashboard/package-lock.json
generated
4
AdminDashboard/package-lock.json
generated
@@ -58,6 +58,7 @@
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/web-push": "^3.6.4",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.7.2",
|
||||
@@ -77,7 +78,6 @@
|
||||
"json5": "^2.2.3",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^12.0.2",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
@@ -121,6 +121,7 @@
|
||||
"universal-cookie": "^7.2.1",
|
||||
"use-async-effect": "^2.2.6",
|
||||
"uuid": "^8.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"zod": "^3.25.30"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -135,7 +136,6 @@
|
||||
"@types/jest": "^28.1.4",
|
||||
"@types/json2csv": "^5.0.3",
|
||||
"@types/jsonwebtoken": "^8.5.9",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/node": "^17.0.45",
|
||||
"@types/node-cron": "^3.0.7",
|
||||
"@types/nodemailer": "^6.4.7",
|
||||
|
||||
@@ -67,7 +67,7 @@ const DashboardFooter: () => JSX.Element = () => {
|
||||
return (
|
||||
<>
|
||||
<Footer
|
||||
className="bg-white h-16 inset-x-0 bottom-0 px-8"
|
||||
className="bg-white px-8"
|
||||
copyright="HackerBay, Inc."
|
||||
links={[
|
||||
{
|
||||
|
||||
@@ -2,36 +2,33 @@ import PageMap from "../../Utils/PageMap";
|
||||
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
|
||||
import Route from "Common/Types/API/Route";
|
||||
import IconProp from "Common/Types/Icon/IconProp";
|
||||
import NavBar from "Common/UI/Components/Navbar/NavBar";
|
||||
import NavBarItem from "Common/UI/Components/Navbar/NavBarItem";
|
||||
import NavBar, { NavItem } from "Common/UI/Components/Navbar/NavBar";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
|
||||
const DashboardNavbar: FunctionComponent = (): ReactElement => {
|
||||
return (
|
||||
<NavBar>
|
||||
<NavBarItem
|
||||
title="Users"
|
||||
icon={IconProp.User}
|
||||
route={RouteUtil.populateRouteParams(RouteMap[PageMap.USERS] as Route)}
|
||||
></NavBarItem>
|
||||
// Build the navigation items
|
||||
const navItems: NavItem[] = [
|
||||
{
|
||||
id: "users-nav-bar-item",
|
||||
title: "Users",
|
||||
icon: IconProp.User,
|
||||
route: RouteUtil.populateRouteParams(RouteMap[PageMap.USERS] as Route),
|
||||
},
|
||||
{
|
||||
id: "projects-nav-bar-item",
|
||||
title: "Projects",
|
||||
icon: IconProp.Folder,
|
||||
route: RouteUtil.populateRouteParams(RouteMap[PageMap.PROJECTS] as Route),
|
||||
},
|
||||
{
|
||||
id: "settings-nav-bar-item",
|
||||
title: "Settings",
|
||||
icon: IconProp.Settings,
|
||||
route: RouteUtil.populateRouteParams(RouteMap[PageMap.SETTINGS] as Route),
|
||||
},
|
||||
];
|
||||
|
||||
<NavBarItem
|
||||
title="Projects"
|
||||
icon={IconProp.Folder}
|
||||
route={RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.PROJECTS] as Route,
|
||||
)}
|
||||
></NavBarItem>
|
||||
|
||||
<NavBarItem
|
||||
title="Settings"
|
||||
icon={IconProp.Settings}
|
||||
route={RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.SETTINGS] as Route,
|
||||
)}
|
||||
></NavBarItem>
|
||||
</NavBar>
|
||||
);
|
||||
return <NavBar items={navItems} />;
|
||||
};
|
||||
|
||||
export default DashboardNavbar;
|
||||
|
||||
@@ -241,6 +241,7 @@ const Projects: FunctionComponent = (): ReactElement => {
|
||||
},
|
||||
title: "Created At",
|
||||
type: FieldType.DateTime,
|
||||
hideOnMobile: true,
|
||||
},
|
||||
]}
|
||||
userPreferencesKey="admin-projects-table"
|
||||
|
||||
@@ -21,7 +21,7 @@ import React, { FunctionComponent, ReactElement, useEffect } from "react";
|
||||
|
||||
const Settings: FunctionComponent = (): ReactElement => {
|
||||
const [emailServerType, setemailServerType] = React.useState<EmailServerType>(
|
||||
EmailServerType.Internal,
|
||||
EmailServerType.CustomSMTP,
|
||||
);
|
||||
|
||||
const [isLoading, setIsLoading] = React.useState<boolean>(true);
|
||||
@@ -43,7 +43,7 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
|
||||
if (globalConfig) {
|
||||
setemailServerType(
|
||||
globalConfig.emailServerType || EmailServerType.Internal,
|
||||
globalConfig.emailServerType || EmailServerType.CustomSMTP,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
/>
|
||||
|
||||
<CardModelDetail
|
||||
name="Internal SMTP Settings"
|
||||
name="Email Server Settings"
|
||||
cardProps={{
|
||||
title: "Email Server Settings",
|
||||
description:
|
||||
@@ -172,7 +172,7 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
cardProps={{
|
||||
title: "Custom Email and SMTP Settings",
|
||||
description:
|
||||
"If you have not enabled Internal SMTP server to send emails. Please configure your SMTP server here.",
|
||||
"Please configure your SMTP server here to send emails.",
|
||||
}}
|
||||
isEditable={true}
|
||||
editButtonText="Edit SMTP Config"
|
||||
|
||||
@@ -54,6 +54,7 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
title="Need help with setting up Global Probes?"
|
||||
description="Here is a guide which will help you get set up"
|
||||
link={Route.fromString("/docs/probe/custom-probe")}
|
||||
hideOnMobile={true}
|
||||
/>
|
||||
|
||||
<ModelTable<Probe>
|
||||
@@ -174,6 +175,7 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
noValueMessage: "-",
|
||||
title: "Description",
|
||||
type: FieldType.LongText,
|
||||
hideOnMobile: true,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
@@ -181,6 +183,7 @@ const Settings: FunctionComponent = (): ReactElement => {
|
||||
},
|
||||
title: "Status",
|
||||
type: FieldType.Text,
|
||||
|
||||
getElement: (item: Probe): ReactElement => {
|
||||
if (
|
||||
item &&
|
||||
|
||||
@@ -116,6 +116,7 @@ const Users: FunctionComponent = (): ReactElement => {
|
||||
},
|
||||
title: "Email Verified",
|
||||
type: FieldType.Boolean,
|
||||
hideOnMobile: true,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
@@ -123,6 +124,7 @@ const Users: FunctionComponent = (): ReactElement => {
|
||||
},
|
||||
title: "Created At",
|
||||
type: FieldType.DateTime,
|
||||
hideOnMobile: true,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -65,6 +65,8 @@ CMD [ "npm", "run", "dev" ]
|
||||
COPY ./App /usr/src/app
|
||||
# Bundle app source
|
||||
RUN npm run compile
|
||||
# Set permission to write logs and cache in case container run as non root
|
||||
RUN chown -R 1000:1000 "/tmp/npm" && chmod -R 2777 "/tmp/npm"
|
||||
#Run the app
|
||||
CMD [ "npm", "start" ]
|
||||
{{ end }}
|
||||
|
||||
@@ -29,6 +29,7 @@ import MonitorTest from "Common/Models/DatabaseModels/MonitorTest";
|
||||
import UserEmailAPI from "Common/Server/API/UserEmailAPI";
|
||||
import UserNotificationLogTimelineAPI from "Common/Server/API/UserOnCallLogTimelineAPI";
|
||||
import UserSMSAPI from "Common/Server/API/UserSmsAPI";
|
||||
import UserPushAPI from "Common/Server/API/UserPushAPI";
|
||||
import ApiKeyPermissionService, {
|
||||
Service as ApiKeyPermissionServiceType,
|
||||
} from "Common/Server/Services/ApiKeyPermissionService";
|
||||
@@ -1608,6 +1609,7 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
);
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserEmailAPI().getRouter());
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserSMSAPI().getRouter());
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserPushAPI().getRouter());
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new ProbeAPI().getRouter());
|
||||
|
||||
app.use(
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import Hostname from "Common/Types/API/Hostname";
|
||||
import TwilioConfig from "Common/Types/CallAndSMS/TwilioConfig";
|
||||
import Email from "Common/Types/Email";
|
||||
import EmailServer from "Common/Types/Email/EmailServer";
|
||||
import BadDataException from "Common/Types/Exception/BadDataException";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
import Port from "Common/Types/Port";
|
||||
import { AdminDashboardClientURL } from "Common/Server/EnvironmentConfig";
|
||||
import GlobalConfigService from "Common/Server/Services/GlobalConfigService";
|
||||
import GlobalConfig, {
|
||||
@@ -12,24 +10,6 @@ import GlobalConfig, {
|
||||
} from "Common/Models/DatabaseModels/GlobalConfig";
|
||||
import Phone from "Common/Types/Phone";
|
||||
|
||||
export const InternalSmtpPassword: string =
|
||||
process.env["INTERNAL_SMTP_PASSWORD"] || "";
|
||||
|
||||
export const InternalSmtpHost: Hostname = new Hostname(
|
||||
process.env["INTERNAL_SMTP_HOST"] || "haraka",
|
||||
);
|
||||
|
||||
export const InternalSmtpPort: Port = new Port(2525);
|
||||
|
||||
export const InternalSmtpSecure: boolean = false;
|
||||
|
||||
export const InternalSmtpEmail: Email = new Email(
|
||||
process.env["INTERNAL_SMTP_EMAIL"] || "noreply@oneuptime.com",
|
||||
);
|
||||
|
||||
export const InternalSmtpFromName: string =
|
||||
process.env["INTERNAL_SMTP_FROM_NAME"] || "OneUptime";
|
||||
|
||||
type GetGlobalSMTPConfig = () => Promise<EmailServer | null>;
|
||||
|
||||
export const getGlobalSMTPConfig: GetGlobalSMTPConfig =
|
||||
@@ -132,10 +112,10 @@ export const getEmailServerType: GetEmailServerTypeFunction =
|
||||
});
|
||||
|
||||
if (!globalConfig) {
|
||||
return EmailServerType.Internal;
|
||||
return EmailServerType.CustomSMTP;
|
||||
}
|
||||
|
||||
return globalConfig.emailServerType || EmailServerType.Internal;
|
||||
return globalConfig.emailServerType || EmailServerType.CustomSMTP;
|
||||
};
|
||||
|
||||
export interface SendGridConfig {
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import {
|
||||
InternalSmtpEmail,
|
||||
InternalSmtpFromName,
|
||||
InternalSmtpHost,
|
||||
InternalSmtpPassword,
|
||||
InternalSmtpPort,
|
||||
InternalSmtpSecure,
|
||||
SendGridConfig,
|
||||
getEmailServerType,
|
||||
getGlobalSMTPConfig,
|
||||
@@ -37,6 +31,98 @@ import nodemailer, { Transporter } from "nodemailer";
|
||||
import Path from "path";
|
||||
import * as tls from "tls";
|
||||
|
||||
// Connection pool for email transporters
|
||||
class TransporterPool {
|
||||
private static pools: Map<string, Transporter> = new Map();
|
||||
private static semaphore: Map<string, number> = new Map();
|
||||
private static readonly MAX_CONCURRENT_CONNECTIONS = 100;
|
||||
|
||||
public static getTransporter(
|
||||
emailServer: EmailServer,
|
||||
options: { timeout?: number | undefined },
|
||||
): Transporter {
|
||||
const key: string = `${emailServer.host.toString()}:${emailServer.port.toNumber()}:${emailServer.username || "noauth"}`;
|
||||
|
||||
if (!this.pools.has(key)) {
|
||||
const transporter: Transporter = this.createTransporter(
|
||||
emailServer,
|
||||
options,
|
||||
);
|
||||
this.pools.set(key, transporter);
|
||||
this.semaphore.set(key, 0);
|
||||
}
|
||||
|
||||
return this.pools.get(key)!;
|
||||
}
|
||||
|
||||
private static createTransporter(
|
||||
emailServer: EmailServer,
|
||||
options: { timeout?: number | undefined },
|
||||
): Transporter {
|
||||
let tlsOptions: tls.ConnectionOptions | undefined = undefined;
|
||||
|
||||
if (!emailServer.secure) {
|
||||
tlsOptions = {
|
||||
rejectUnauthorized: false,
|
||||
};
|
||||
}
|
||||
|
||||
return nodemailer.createTransport({
|
||||
host: emailServer.host.toString(),
|
||||
port: emailServer.port.toNumber(),
|
||||
secure: emailServer.secure,
|
||||
tls: tlsOptions,
|
||||
auth:
|
||||
emailServer.username && emailServer.password
|
||||
? {
|
||||
user: emailServer.username,
|
||||
pass: emailServer.password,
|
||||
}
|
||||
: undefined,
|
||||
connectionTimeout: options.timeout || 60000,
|
||||
pool: true, // Enable connection pooling
|
||||
maxConnections: this.MAX_CONCURRENT_CONNECTIONS,
|
||||
});
|
||||
}
|
||||
|
||||
public static async acquireConnection(
|
||||
emailServer: EmailServer,
|
||||
): Promise<void> {
|
||||
const key: string = `${emailServer.host.toString()}:${emailServer.port.toNumber()}:${emailServer.username || "noauth"}`;
|
||||
|
||||
while ((this.semaphore.get(key) || 0) >= this.MAX_CONCURRENT_CONNECTIONS) {
|
||||
await new Promise<void>((resolve: () => void) => {
|
||||
setTimeout(resolve, 100);
|
||||
});
|
||||
}
|
||||
|
||||
this.semaphore.set(key, (this.semaphore.get(key) || 0) + 1);
|
||||
}
|
||||
|
||||
public static releaseConnection(emailServer: EmailServer): void {
|
||||
const key: string = `${emailServer.host.toString()}:${emailServer.port.toNumber()}:${emailServer.username || "noauth"}`;
|
||||
const current: number = this.semaphore.get(key) || 0;
|
||||
this.semaphore.set(key, Math.max(0, current - 1));
|
||||
}
|
||||
|
||||
public static async cleanup(): Promise<void> {
|
||||
const closePromises: Promise<void>[] = [];
|
||||
|
||||
for (const [, transporter] of this.pools) {
|
||||
closePromises.push(
|
||||
new Promise<void>((resolve: () => void) => {
|
||||
transporter.close();
|
||||
resolve();
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(closePromises);
|
||||
this.pools.clear();
|
||||
this.semaphore.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export default class MailService {
|
||||
public static isSMTPConfigValid(obj: JSONObject): boolean {
|
||||
if (!obj["SMTP_USERNAME"]) {
|
||||
@@ -110,19 +196,6 @@ export default class MailService {
|
||||
};
|
||||
}
|
||||
|
||||
public static getInternalEmailServer(): EmailServer {
|
||||
return {
|
||||
id: undefined,
|
||||
username: InternalSmtpEmail.toString(),
|
||||
password: InternalSmtpPassword,
|
||||
host: InternalSmtpHost,
|
||||
port: InternalSmtpPort,
|
||||
fromEmail: InternalSmtpEmail,
|
||||
fromName: InternalSmtpFromName,
|
||||
secure: InternalSmtpSecure,
|
||||
};
|
||||
}
|
||||
|
||||
public static async getGlobalFromEmail(): Promise<Email> {
|
||||
const emailServer: EmailServer | null = await this.getGlobalSmtpSettings();
|
||||
|
||||
@@ -205,30 +278,7 @@ export default class MailService {
|
||||
timeout?: number | undefined;
|
||||
},
|
||||
): Transporter {
|
||||
let tlsOptions: tls.ConnectionOptions | undefined = undefined;
|
||||
|
||||
if (!emailServer.secure) {
|
||||
tlsOptions = {
|
||||
rejectUnauthorized: false,
|
||||
};
|
||||
}
|
||||
|
||||
const privateMailer: Transporter = nodemailer.createTransport({
|
||||
host: emailServer.host.toString(),
|
||||
port: emailServer.port.toNumber(),
|
||||
secure: emailServer.secure,
|
||||
tls: tlsOptions,
|
||||
auth:
|
||||
emailServer.username && emailServer.password
|
||||
? {
|
||||
user: emailServer.username,
|
||||
pass: emailServer.password,
|
||||
}
|
||||
: undefined,
|
||||
connectionTimeout: options.timeout || undefined,
|
||||
});
|
||||
|
||||
return privateMailer;
|
||||
return TransporterPool.getTransporter(emailServer, options);
|
||||
}
|
||||
|
||||
private static async transportMail(
|
||||
@@ -242,12 +292,49 @@ export default class MailService {
|
||||
const mailer: Transporter = this.createMailer(options.emailServer, {
|
||||
timeout: options.timeout,
|
||||
});
|
||||
await mailer.sendMail({
|
||||
from: `${options.emailServer.fromName.toString()} <${options.emailServer.fromEmail.toString()}>`,
|
||||
to: mail.toEmail.toString(),
|
||||
subject: mail.subject,
|
||||
html: mail.body,
|
||||
});
|
||||
|
||||
let lastError: any;
|
||||
const maxRetries: number = 3;
|
||||
|
||||
// Acquire connection slot to prevent overwhelming the server
|
||||
await TransporterPool.acquireConnection(options.emailServer);
|
||||
|
||||
try {
|
||||
for (let attempt: number = 1; attempt <= maxRetries; attempt++) {
|
||||
try {
|
||||
await mailer.sendMail({
|
||||
from: `${options.emailServer.fromName.toString()} <${options.emailServer.fromEmail.toString()}>`,
|
||||
to: mail.toEmail.toString(),
|
||||
subject: mail.subject,
|
||||
html: mail.body,
|
||||
});
|
||||
return; // Success, exit the function
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
logger.error(`Email send attempt ${attempt} failed:`);
|
||||
logger.error(error);
|
||||
|
||||
if (attempt === maxRetries) {
|
||||
break; // Don't wait after the last attempt
|
||||
}
|
||||
|
||||
// Wait before retrying with jitter to prevent thundering herd
|
||||
const baseWaitTime: number = Math.pow(2, attempt - 1) * 1000;
|
||||
const jitter: number = Math.random() * 1000; // Add up to 1 second of jitter
|
||||
const waitTime: number = baseWaitTime + jitter;
|
||||
|
||||
await new Promise<void>((resolve: (value: void) => void) => {
|
||||
setTimeout(resolve, waitTime);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// If we reach here, all retries failed
|
||||
throw lastError;
|
||||
} finally {
|
||||
// Always release the connection slot
|
||||
TransporterPool.releaseConnection(options.emailServer);
|
||||
}
|
||||
}
|
||||
|
||||
public static async send(
|
||||
@@ -434,17 +521,6 @@ export default class MailService {
|
||||
options.emailServer = globalEmailServer;
|
||||
}
|
||||
|
||||
if (
|
||||
emailServerType === EmailServerType.Internal &&
|
||||
(!options || !options.emailServer)
|
||||
) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
options.emailServer = this.getInternalEmailServer();
|
||||
}
|
||||
|
||||
if (options && options.emailServer && emailLog) {
|
||||
emailLog.fromEmail = options.emailServer.fromEmail;
|
||||
}
|
||||
@@ -518,4 +594,8 @@ export default class MailService {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
public static async cleanup(): Promise<void> {
|
||||
await TransporterPool.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
21
App/package-lock.json
generated
21
App/package-lock.json
generated
@@ -35,8 +35,9 @@
|
||||
"version": "1.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@asteasolutions/zod-to-openapi": "^7.3.2",
|
||||
"@bull-board/express": "^5.21.4",
|
||||
"@clickhouse/client": "^0.2.10",
|
||||
"@clickhouse/client": "^1.10.1",
|
||||
"@elastic/elasticsearch": "^8.12.1",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
@@ -64,18 +65,19 @@
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/web-push": "^3.6.4",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.7.2",
|
||||
"bullmq": "^5.3.3",
|
||||
"Common": "file:../Common",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"cron-parser": "^4.8.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dotenv": "^16.4.4",
|
||||
"ejs": "^3.1.10",
|
||||
"express": "^4.19.2",
|
||||
"esbuild": "^0.25.5",
|
||||
"express": "^4.21.1",
|
||||
"formik": "^2.4.6",
|
||||
"history": "^5.3.0",
|
||||
"ioredis": "^5.3.2",
|
||||
@@ -83,7 +85,6 @@
|
||||
"json5": "^2.2.3",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "^12.0.2",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
@@ -91,6 +92,7 @@
|
||||
"nodemailer": "^6.9.10",
|
||||
"otpauth": "^9.3.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright": "^1.50.0",
|
||||
"posthog-js": "^1.139.6",
|
||||
"prop-types": "^15.8.1",
|
||||
"qrcode": "^1.5.3",
|
||||
@@ -113,6 +115,7 @@
|
||||
"redis-semaphore": "^5.5.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"slackify-markdown": "^4.4.0",
|
||||
"slugify": "^1.6.5",
|
||||
"socket.io": "^4.7.4",
|
||||
"socket.io-client": "^4.7.5",
|
||||
@@ -122,9 +125,11 @@
|
||||
"twilio": "^4.22.0",
|
||||
"typeorm": "^0.3.20",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"universal-cookie": "^4.0.4",
|
||||
"universal-cookie": "^7.2.1",
|
||||
"use-async-effect": "^2.2.6",
|
||||
"uuid": "^8.3.2"
|
||||
"uuid": "^8.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"zod": "^3.25.30"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.2",
|
||||
@@ -138,7 +143,6 @@
|
||||
"@types/jest": "^28.1.4",
|
||||
"@types/json2csv": "^5.0.3",
|
||||
"@types/jsonwebtoken": "^8.5.9",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/node": "^17.0.45",
|
||||
"@types/node-cron": "^3.0.7",
|
||||
"@types/nodemailer": "^6.4.7",
|
||||
@@ -152,6 +156,7 @@
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jest-mock-extended": "^3.0.5",
|
||||
"react-test-renderer": "^18.2.0",
|
||||
"sass": "^1.89.2",
|
||||
"ts-jest": "^28.0.5"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -104,6 +104,7 @@ export default class AcmeCertificate extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -80,6 +80,7 @@ export default class AcmeChallenge extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -299,6 +299,7 @@ export default class Alert extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -570,11 +571,13 @@ export default class Alert extends BaseModel {
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Current Alert State ID",
|
||||
description: "Current Alert State ID",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ObjectID,
|
||||
|
||||
nullable: false,
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
@@ -758,12 +761,7 @@ export default class Alert extends BaseModel {
|
||||
public customFields?: JSONObject = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateAlert,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -775,10 +773,13 @@ export default class Alert extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified Of Alert Creation?",
|
||||
description: "Are owners notified of when this alert is created?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -936,6 +937,7 @@ export default class Alert extends BaseModel {
|
||||
title: "Is created automatically?",
|
||||
description:
|
||||
"Is this alert created by OneUptime Probe or Workers automatically (and not created manually by a user)?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -1028,6 +1030,7 @@ export default class Alert extends BaseModel {
|
||||
isDefaultValueColumn: false,
|
||||
required: false,
|
||||
type: TableColumnType.Number,
|
||||
computed: true,
|
||||
title: "Alert Number",
|
||||
description: "Alert Number",
|
||||
})
|
||||
|
||||
@@ -297,6 +297,7 @@ export default class AlertCustomField extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -282,6 +282,7 @@ export default class AlertFeed extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -271,6 +271,7 @@ export default class AlertInternalNote extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -340,12 +341,7 @@ export default class AlertInternalNote extends BaseModel {
|
||||
public note?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateAlertInternalNote,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -357,10 +353,13 @@ export default class AlertInternalNote extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -314,6 +314,7 @@ export default class AlertNoteTemplate extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -64,6 +64,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "AlertOwnerTeam",
|
||||
})
|
||||
@Index(["alertId", "teamId", "projectId"])
|
||||
export default class AlertOwnerTeam extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -343,6 +344,7 @@ export default class AlertOwnerTeam extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -406,6 +408,7 @@ export default class AlertOwnerTeam extends BaseModel {
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -63,6 +63,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "AlertOwnerUser",
|
||||
})
|
||||
@Index(["alertId", "userId", "projectId"])
|
||||
export default class AlertOwnerUser extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -342,6 +343,7 @@ export default class AlertOwnerUser extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -405,6 +407,7 @@ export default class AlertOwnerUser extends BaseModel {
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -76,6 +76,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "AlertSeverity",
|
||||
})
|
||||
@Index(["projectId", "order"])
|
||||
export default class AlertSeverity extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -192,6 +193,7 @@ export default class AlertSeverity extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -314,6 +316,7 @@ export default class AlertSeverity extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -76,6 +76,10 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "AlertState",
|
||||
})
|
||||
@Index(["projectId", "isCreatedState"])
|
||||
@Index(["projectId", "isResolvedState"])
|
||||
@Index(["projectId", "isAcknowledgedState"])
|
||||
@Index(["projectId", "order"])
|
||||
export default class AlertState extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -290,6 +294,7 @@ export default class AlertState extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -60,6 +60,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "AlertStateTimeline",
|
||||
})
|
||||
@Index(["alertId", "startsAt"])
|
||||
@TableMetadata({
|
||||
tableName: "AlertStateTimeline",
|
||||
singularName: "Alert State Timeline",
|
||||
@@ -274,6 +275,7 @@ export default class AlertStateTimeline extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -387,12 +389,7 @@ export default class AlertStateTimeline extends BaseModel {
|
||||
public alertStateId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateAlertStateTimeline,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -404,10 +401,13 @@ export default class AlertStateTimeline extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of state change?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -201,6 +201,7 @@ export default class ApiKey extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -281,6 +282,7 @@ export default class ApiKey extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -347,11 +349,7 @@ export default class ApiKey extends BaseModel {
|
||||
public expiresAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ReadProjectApiKey,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -368,6 +366,7 @@ export default class ApiKey extends BaseModel {
|
||||
type: TableColumnType.ObjectID,
|
||||
isDefaultValueColumn: false,
|
||||
title: "API Key",
|
||||
computed: true,
|
||||
description: "Secret API Key",
|
||||
})
|
||||
@Column({
|
||||
|
||||
@@ -291,6 +291,7 @@ export default class APIKeyPermission extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -425,7 +426,11 @@ export default class APIKeyPermission extends BaseModel {
|
||||
Permission.EditProjectApiKey,
|
||||
],
|
||||
})
|
||||
@TableColumn({ isDefaultValueColumn: true, type: TableColumnType.Boolean })
|
||||
@TableColumn({
|
||||
isDefaultValueColumn: true,
|
||||
type: TableColumnType.Boolean,
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
default: false,
|
||||
|
||||
@@ -172,6 +172,7 @@ export default class BillingInvoice extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -174,6 +174,7 @@ export default class BillingPaymentMethod extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -247,6 +247,7 @@ export default class CallLog extends BaseModel {
|
||||
description: "Call Cost in USD Cents",
|
||||
canReadOnRelationQuery: false,
|
||||
isDefaultValueColumn: true,
|
||||
defaultValue: 0,
|
||||
})
|
||||
@Column({
|
||||
nullable: false,
|
||||
@@ -264,6 +265,7 @@ export default class CallLog extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -289,6 +289,7 @@ export default class CopilotAction extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -250,6 +250,7 @@ export default class CopilotActionTypePriority extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -208,6 +208,7 @@ export default class CopilotCodeRepository extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -334,6 +335,7 @@ export default class CopilotCodeRepository extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -425,12 +427,7 @@ export default class CopilotCodeRepository extends BaseModel {
|
||||
public labels?: Array<Label> = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateCopilotCodeRepository,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -449,6 +446,7 @@ export default class CopilotCodeRepository extends BaseModel {
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
isDefaultValueColumn: false,
|
||||
computed: true,
|
||||
title: "Secret Token",
|
||||
description:
|
||||
"Secret Token for this code repository. This is used to connect this code repository to OneUptime.",
|
||||
|
||||
@@ -237,6 +237,7 @@ export default class CopilotPullRequest extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -188,6 +188,7 @@ export default class Dashboard extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -306,6 +307,7 @@ export default class Dashboard extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -145,6 +145,7 @@ export default class DataMigration extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -56,6 +56,7 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
title: "ID",
|
||||
type: TableColumnType.ObjectID,
|
||||
description: "ID of this object",
|
||||
computed: true,
|
||||
})
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
public _id?: string = undefined;
|
||||
@@ -63,6 +64,7 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
@TableColumn({
|
||||
title: "Created At",
|
||||
type: TableColumnType.Date,
|
||||
computed: true,
|
||||
description: "Date and Time when the object was created.",
|
||||
})
|
||||
@CreateDateColumn({
|
||||
@@ -73,6 +75,7 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
@TableColumn({
|
||||
title: "Updated At",
|
||||
type: TableColumnType.Date,
|
||||
computed: true,
|
||||
description: "Date and Time when the object was updated.",
|
||||
})
|
||||
@UpdateDateColumn({
|
||||
@@ -83,6 +86,7 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
@TableColumn({
|
||||
title: "Deleted At",
|
||||
type: TableColumnType.Date,
|
||||
computed: true,
|
||||
description: "Date and Time when the object was deleted.",
|
||||
})
|
||||
@DeleteDateColumn({
|
||||
@@ -93,6 +97,7 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
@TableColumn({
|
||||
title: "Version",
|
||||
type: TableColumnType.Number,
|
||||
computed: true,
|
||||
description: "Object version",
|
||||
hideColumnInDocumentation: true,
|
||||
})
|
||||
@@ -651,7 +656,13 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
json = JSONFunctions.deserialize(json);
|
||||
const baseModel: T = new type();
|
||||
|
||||
for (const key of Object.keys(json)) {
|
||||
for (let key of Object.keys(json)) {
|
||||
if (key === "id") {
|
||||
key = "_id";
|
||||
json["_id"] = json["id"];
|
||||
delete json["id"];
|
||||
}
|
||||
|
||||
const tableColumnMetadata: TableColumnMetadata =
|
||||
baseModel.getTableColumnMetadata(key);
|
||||
if (tableColumnMetadata) {
|
||||
|
||||
@@ -21,8 +21,8 @@ export default class FileModel extends BaseModel {
|
||||
}
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
create: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
read: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
@@ -37,8 +37,8 @@ export default class FileModel extends BaseModel {
|
||||
public file?: Buffer = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
create: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
read: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
@@ -56,8 +56,8 @@ export default class FileModel extends BaseModel {
|
||||
public name?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
create: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
read: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
@@ -73,8 +73,8 @@ export default class FileModel extends BaseModel {
|
||||
public fileType?: MimeType = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
create: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
read: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
@@ -91,8 +91,8 @@ export default class FileModel extends BaseModel {
|
||||
public slug?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
create: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
read: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
|
||||
@@ -170,6 +170,7 @@ export default class Domain extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -257,6 +258,7 @@ export default class Domain extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -317,6 +319,7 @@ export default class Domain extends BaseModel {
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Verified",
|
||||
description: "Is this domain verified?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -298,6 +298,7 @@ export default class EmailLog extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -125,6 +125,7 @@ export default class EmailVerificationToken extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -2,11 +2,13 @@ import FileModel from "./DatabaseBaseModel/FileModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import Permission from "../../Types/Permission";
|
||||
import { Entity } from "typeorm";
|
||||
|
||||
@EnableDocumentation()
|
||||
@TableMetadata({
|
||||
tableName: "File",
|
||||
singularName: "File",
|
||||
@@ -19,8 +21,8 @@ import { Entity } from "typeorm";
|
||||
})
|
||||
@CrudApiEndpoint(new Route("/file"))
|
||||
@TableAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
create: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
read: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
delete: [],
|
||||
update: [],
|
||||
})
|
||||
|
||||
@@ -17,7 +17,6 @@ import Port from "../../Types/Port";
|
||||
import { Column, Entity } from "typeorm";
|
||||
|
||||
export enum EmailServerType {
|
||||
Internal = "Internal",
|
||||
Sendgrid = "Sendgrid",
|
||||
CustomSMTP = "Custom SMTP",
|
||||
}
|
||||
@@ -260,7 +259,7 @@ export default class GlobalConfig extends GlobalConfigModel {
|
||||
nullable: true,
|
||||
unique: false,
|
||||
})
|
||||
public twilioSecondaryPhoneNumbers?: string = undefined; // phone numbers seperated by comma
|
||||
public twilioSecondaryPhoneNumbers?: string = undefined; // phone numbers separated by comma
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
@@ -355,6 +354,7 @@ export default class GlobalConfig extends GlobalConfigModel {
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
computed: true,
|
||||
title: "Master API Key",
|
||||
description:
|
||||
"This API key has root access to all the resources in all the projects on OneUptime.",
|
||||
|
||||
@@ -61,7 +61,7 @@ export default class GreenlockCertificate extends BaseModel {
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({ type: TableColumnType.Boolean })
|
||||
@TableColumn({ type: TableColumnType.Boolean, defaultValue: false })
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
nullable: false,
|
||||
@@ -79,6 +79,7 @@ export default class GreenlockCertificate extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -80,6 +80,7 @@ export default class GreenlockChallenge extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -229,12 +229,7 @@ export default class Incident extends BaseModel {
|
||||
|
||||
@Index()
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectIncident,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -247,6 +242,7 @@ export default class Incident extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -332,6 +328,7 @@ export default class Incident extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -530,6 +527,7 @@ export default class Incident extends BaseModel {
|
||||
@TableColumn({
|
||||
manyToOneRelationColumn: "currentIncidentStateId",
|
||||
type: TableColumnType.Entity,
|
||||
computed: true,
|
||||
modelType: IncidentState,
|
||||
title: "Current Incident State",
|
||||
description:
|
||||
@@ -571,6 +569,7 @@ export default class Incident extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
isDefaultValueColumn: true,
|
||||
required: true,
|
||||
title: "Current Incident State ID",
|
||||
description: "Current Incident State ID",
|
||||
@@ -745,9 +744,12 @@ export default class Incident extends BaseModel {
|
||||
})
|
||||
@TableColumn({
|
||||
isDefaultValueColumn: true,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Are subscribers notified?",
|
||||
description: "Are subscribers notified about this incident?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -775,6 +777,7 @@ export default class Incident extends BaseModel {
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Should subscribers be notified?",
|
||||
description: "Should subscribers be notified about this incident?",
|
||||
defaultValue: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -817,12 +820,7 @@ export default class Incident extends BaseModel {
|
||||
public customFields?: JSONObject = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectIncident,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -834,10 +832,13 @@ export default class Incident extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified Of Resource Creation?",
|
||||
description: "Are owners notified of when this resource is created?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -1025,6 +1026,7 @@ export default class Incident extends BaseModel {
|
||||
title: "Is created automatically?",
|
||||
description:
|
||||
"Is this incident created by OneUptime Probe or Workers automatically (and not created manually by a user)?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -1099,12 +1101,7 @@ export default class Incident extends BaseModel {
|
||||
public telemetryQuery?: TelemetryQuery = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectIncident,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -1120,6 +1117,7 @@ export default class Incident extends BaseModel {
|
||||
type: TableColumnType.Number,
|
||||
title: "Incident Number",
|
||||
description: "Incident Number",
|
||||
computed: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Number,
|
||||
@@ -1171,6 +1169,7 @@ export default class Incident extends BaseModel {
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Should be visible on status page?",
|
||||
description: "Should this incident be visible on the status page?",
|
||||
defaultValue: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -297,6 +297,7 @@ export default class IncidentCustomField extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -282,6 +282,7 @@ export default class IncidentFeed extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -271,6 +271,7 @@ export default class IncidentInternalNote extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -340,12 +341,7 @@ export default class IncidentInternalNote extends BaseModel {
|
||||
public note?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentInternalNote,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -357,10 +353,13 @@ export default class IncidentInternalNote extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -314,6 +314,7 @@ export default class IncidentNoteTemplate extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -64,6 +64,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "IncidentOwnerTeam",
|
||||
})
|
||||
@Index(["incidentId", "teamId", "projectId"])
|
||||
export default class IncidentOwnerTeam extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -343,6 +344,7 @@ export default class IncidentOwnerTeam extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -385,12 +387,7 @@ export default class IncidentOwnerTeam extends BaseModel {
|
||||
public deletedByUserId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentOwnerTeam,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -402,10 +399,13 @@ export default class IncidentOwnerTeam extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -63,6 +63,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "IncidentOwnerUser",
|
||||
})
|
||||
@Index(["incidentId", "userId", "projectId"])
|
||||
export default class IncidentOwnerUser extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -342,6 +343,7 @@ export default class IncidentOwnerUser extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -405,6 +407,7 @@ export default class IncidentOwnerUser extends BaseModel {
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -271,6 +271,7 @@ export default class IncidentPublicNote extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -351,9 +352,12 @@ export default class IncidentPublicNote extends BaseModel {
|
||||
})
|
||||
@TableColumn({
|
||||
isDefaultValueColumn: true,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Are subscribers notified?",
|
||||
description: "Are subscribers notified about this note?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -381,6 +385,7 @@ export default class IncidentPublicNote extends BaseModel {
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Should subscribers be notified?",
|
||||
description: "Should subscribers be notified about this note?",
|
||||
defaultValue: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -390,12 +395,7 @@ export default class IncidentPublicNote extends BaseModel {
|
||||
undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentPublicNote,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -407,10 +407,13 @@ export default class IncidentPublicNote extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -76,6 +76,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "IncidentSeverity",
|
||||
})
|
||||
@Index(["projectId", "order"])
|
||||
export default class IncidentSeverity extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -192,6 +193,7 @@ export default class IncidentSeverity extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -314,6 +316,7 @@ export default class IncidentSeverity extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -76,6 +76,9 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "IncidentState",
|
||||
})
|
||||
@Index(["projectId", "isCreatedState"])
|
||||
@Index(["projectId", "isResolvedState"])
|
||||
@Index(["projectId", "order"])
|
||||
export default class IncidentState extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -192,6 +195,7 @@ export default class IncidentState extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -314,6 +318,7 @@ export default class IncidentState extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -24,6 +24,8 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@EnableDocumentation()
|
||||
@CanAccessIfCanReadOn("incident")
|
||||
@TenantColumn("projectId")
|
||||
@Index(["incidentId", "startsAt"]) // Composite index for efficient incident timeline queries
|
||||
@Index(["incidentId", "projectId", "startsAt"]) // Alternative composite index including project
|
||||
@TableAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
@@ -60,6 +62,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "IncidentStateTimeline",
|
||||
})
|
||||
@Index(["incidentId", "startsAt"])
|
||||
@TableMetadata({
|
||||
tableName: "IncidentStateTimeline",
|
||||
singularName: "Incident State Timeline",
|
||||
@@ -274,6 +277,7 @@ export default class IncidentStateTimeline extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -387,12 +391,7 @@ export default class IncidentStateTimeline extends BaseModel {
|
||||
public incidentStateId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentStateTimeline,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -403,9 +402,12 @@ export default class IncidentStateTimeline extends BaseModel {
|
||||
})
|
||||
@TableColumn({
|
||||
isDefaultValueColumn: true,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Are subscribers notified?",
|
||||
description: "Are subscribers notified about this incident state change?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -441,12 +443,7 @@ export default class IncidentStateTimeline extends BaseModel {
|
||||
public shouldStatusPageSubscribersBeNotified?: boolean = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentStateTimeline,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -458,6 +455,8 @@ export default class IncidentStateTimeline extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
|
||||
@@ -295,12 +295,7 @@ export default class IncidentTemplate extends BaseModel {
|
||||
|
||||
@Index()
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentTemplate,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -313,6 +308,7 @@ export default class IncidentTemplate extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -398,6 +394,7 @@ export default class IncidentTemplate extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -345,6 +345,7 @@ export default class IncidentTemplateOwnerTeam extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -387,12 +388,7 @@ export default class IncidentTemplateOwnerTeam extends BaseModel {
|
||||
public deletedByUserId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentTemplateOwnerTeam,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -404,10 +400,13 @@ export default class IncidentTemplateOwnerTeam extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -354,6 +354,7 @@ export default class IncidentTemplateOwnerUser extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -397,12 +398,7 @@ export default class IncidentTemplateOwnerUser extends BaseModel {
|
||||
public deletedByUserId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentTemplateOwnerUser,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -415,10 +411,13 @@ export default class IncidentTemplateOwnerUser extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -126,6 +126,7 @@ import User from "./User";
|
||||
import UserCall from "./UserCall";
|
||||
// Notification Methods
|
||||
import UserEmail from "./UserEmail";
|
||||
import UserPush from "./UserPush";
|
||||
// User Notification Rules
|
||||
import UserNotificationRule from "./UserNotificationRule";
|
||||
import UserNotificationSetting from "./UserNotificationSetting";
|
||||
@@ -294,6 +295,7 @@ const AllModelTypes: Array<{
|
||||
UserEmail,
|
||||
UserSms,
|
||||
UserCall,
|
||||
UserPush,
|
||||
|
||||
UserNotificationRule,
|
||||
UserOnCallLog,
|
||||
|
||||
@@ -186,6 +186,7 @@ export default class Label extends AccessControlModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -304,6 +305,7 @@ export default class Label extends AccessControlModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -57,10 +57,10 @@ import TelemetryService from "./TelemetryService";
|
||||
],
|
||||
})
|
||||
@EnableWorkflow({
|
||||
create: true,
|
||||
delete: true,
|
||||
update: true,
|
||||
read: true,
|
||||
create: false,
|
||||
delete: false,
|
||||
update: false,
|
||||
read: false,
|
||||
})
|
||||
@CrudApiEndpoint(new Route("/metric-type"))
|
||||
@SlugifyColumn("name", "slug")
|
||||
@@ -359,6 +359,7 @@ export default class MetricType extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -221,12 +221,7 @@ export default class Monitor extends BaseModel {
|
||||
|
||||
@Index()
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -239,6 +234,7 @@ export default class Monitor extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -324,6 +320,7 @@ export default class Monitor extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -480,7 +477,7 @@ export default class Monitor extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
Permission.CreateProjectIncident,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
@@ -499,6 +496,7 @@ export default class Monitor extends BaseModel {
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Current Monitor Status ID",
|
||||
description: "Whats the current status ID of this monitor?",
|
||||
canReadOnRelationQuery: true,
|
||||
@@ -611,12 +609,7 @@ export default class Monitor extends BaseModel {
|
||||
public customFields?: JSONObject = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -628,10 +621,13 @@ export default class Monitor extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified Of Resource Creation?",
|
||||
description: "Are owners notified of when this resource is created?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -667,6 +663,7 @@ export default class Monitor extends BaseModel {
|
||||
isDefaultValueColumn: true,
|
||||
title: "Disable Monitoring",
|
||||
description: "Disable active monitoring for this resource?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -784,6 +781,7 @@ export default class Monitor extends BaseModel {
|
||||
title: "Disable Monitoring because of Ongoing Scheduled Maintenance Event",
|
||||
description:
|
||||
"Disable Monitoring because of Ongoing Scheduled Maintenance Event",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -811,6 +809,7 @@ export default class Monitor extends BaseModel {
|
||||
title: "Disable Monitoring because of Manual Incident",
|
||||
description:
|
||||
"Disable Monitoring because of Incident which is creeated manually by user.",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -850,12 +849,7 @@ export default class Monitor extends BaseModel {
|
||||
public serverMonitorRequestReceivedAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -874,6 +868,7 @@ export default class Monitor extends BaseModel {
|
||||
type: TableColumnType.ObjectID,
|
||||
required: false,
|
||||
isDefaultValueColumn: false,
|
||||
computed: true,
|
||||
title: "Server Monitor Secret Key",
|
||||
description:
|
||||
"This field is for Server Monitor only. Secret Key to authenticate the request.",
|
||||
@@ -886,12 +881,7 @@ export default class Monitor extends BaseModel {
|
||||
public serverMonitorSecretKey?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -910,6 +900,7 @@ export default class Monitor extends BaseModel {
|
||||
type: TableColumnType.ObjectID,
|
||||
required: false,
|
||||
isDefaultValueColumn: false,
|
||||
computed: true,
|
||||
title: "Incoming Request Secret Key",
|
||||
description:
|
||||
"This field is for Incoming Request Monitor only. Secret Key to authenticate the request.",
|
||||
@@ -993,6 +984,7 @@ export default class Monitor extends BaseModel {
|
||||
title: "All Probes Disconnected From This Monitor",
|
||||
description:
|
||||
"All Probes Disconnected From This Monitor. Is this monitor not being monitored?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
@@ -1017,6 +1009,7 @@ export default class Monitor extends BaseModel {
|
||||
title: "No Probe Enabled On This Monitor",
|
||||
description:
|
||||
"No Probe Enabled On This Monitor. Is this monitor not being monitored?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -297,6 +297,7 @@ export default class MonitorCustomField extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -276,6 +276,7 @@ export default class MonitorFeed extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -222,12 +222,7 @@ export default class MonitorGroup extends BaseModel {
|
||||
|
||||
@Index()
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateMonitorGroup,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -240,6 +235,7 @@ export default class MonitorGroup extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -325,6 +321,7 @@ export default class MonitorGroup extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -353,6 +353,7 @@ export default class MonitorGroupOwnerTeam extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -395,12 +396,7 @@ export default class MonitorGroupOwnerTeam extends BaseModel {
|
||||
public deletedByUserId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateMonitorGroupOwnerTeam,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -412,10 +408,13 @@ export default class MonitorGroupOwnerTeam extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -352,6 +352,7 @@ export default class MonitorGroupOwnerUser extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -394,12 +395,7 @@ export default class MonitorGroupOwnerUser extends BaseModel {
|
||||
public deletedByUserId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateMonitorGroupOwnerUser,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -411,10 +407,13 @@ export default class MonitorGroupOwnerUser extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -348,6 +348,7 @@ export default class MonitorGroupResource extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -72,6 +72,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "MonitorOwnerTeam",
|
||||
})
|
||||
@Index(["monitorId", "teamId", "projectId"])
|
||||
export default class MonitorOwnerTeam extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -351,6 +352,7 @@ export default class MonitorOwnerTeam extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -414,6 +416,7 @@ export default class MonitorOwnerTeam extends BaseModel {
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -71,6 +71,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "MonitorOwnerUser",
|
||||
})
|
||||
@Index(["monitorId", "userId", "projectId"])
|
||||
export default class MonitorOwnerUser extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -350,6 +351,7 @@ export default class MonitorOwnerUser extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -413,6 +415,7 @@ export default class MonitorOwnerUser extends BaseModel {
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of this resource ownership?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -24,6 +24,8 @@ export type MonitorStepProbeResponse = Dictionary<ProbeMonitorResponse>;
|
||||
|
||||
@EnableDocumentation()
|
||||
@TenantColumn("projectId")
|
||||
@Index(["monitorId", "probeId"]) // Composite index for efficient monitor-probe relationship queries
|
||||
@Index(["monitorId", "projectId"]) // Alternative index for monitor queries within project
|
||||
@TableAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
@@ -376,6 +378,7 @@ export default class MonitorProbe extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -440,6 +443,7 @@ export default class MonitorProbe extends BaseModel {
|
||||
isDefaultValueColumn: true,
|
||||
required: true,
|
||||
type: TableColumnType.Boolean,
|
||||
defaultValue: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -359,6 +359,7 @@ export default class MonitorSecret extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -76,6 +76,8 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "MonitorStatus",
|
||||
})
|
||||
@Index(["projectId", "isOperationalState"])
|
||||
@Index(["projectId", "isOfflineState"])
|
||||
export default class MonitorStatus extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
@@ -192,6 +194,7 @@ export default class MonitorStatus extends BaseModel {
|
||||
required: true,
|
||||
unique: true,
|
||||
type: TableColumnType.Slug,
|
||||
computed: true,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
})
|
||||
@@ -314,6 +317,7 @@ export default class MonitorStatus extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -418,6 +422,7 @@ export default class MonitorStatus extends BaseModel {
|
||||
canReadOnRelationQuery: true,
|
||||
title: "Is Operational State",
|
||||
description: "Is this monitor in operational state?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -25,6 +25,8 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@EnableDocumentation()
|
||||
@CanAccessIfCanReadOn("monitor")
|
||||
@TenantColumn("projectId")
|
||||
@Index(["monitorId", "projectId", "startsAt"]) // Composite index for efficient timeline queries
|
||||
@Index(["monitorId", "startsAt"]) // Alternative index for monitor-specific timeline queries
|
||||
@TableAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
@@ -62,6 +64,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@Entity({
|
||||
name: "MonitorStatusTimeline",
|
||||
})
|
||||
@Index(["monitorId", "startsAt"])
|
||||
@TableMetadata({
|
||||
tableName: "MonitorStatusTimeline",
|
||||
singularName: "Monitor Status Event",
|
||||
@@ -276,6 +279,7 @@ export default class MonitorStatusTimeline extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -389,12 +393,7 @@ export default class MonitorStatusTimeline extends BaseModel {
|
||||
public monitorStatusId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateMonitorStatusTimeline,
|
||||
],
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
@@ -406,10 +405,13 @@ export default class MonitorStatusTimeline extends BaseModel {
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
computed: true,
|
||||
hideColumnInDocumentation: true,
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
title: "Are Owners Notified",
|
||||
description: "Are owners notified of status change?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -210,6 +210,7 @@ export default class MonitorTest extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -468,6 +469,7 @@ export default class MonitorTest extends BaseModel {
|
||||
isDefaultValueColumn: false,
|
||||
required: true,
|
||||
type: TableColumnType.Boolean,
|
||||
defaultValue: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
|
||||
@@ -276,6 +276,7 @@ export default class OnCallDutyPolicy extends BaseModel {
|
||||
type: TableColumnType.Slug,
|
||||
title: "Slug",
|
||||
description: "Friendly globally unique name for your object",
|
||||
computed: true,
|
||||
})
|
||||
@Column({
|
||||
nullable: false,
|
||||
@@ -359,6 +360,7 @@ export default class OnCallDutyPolicy extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -421,6 +423,7 @@ export default class OnCallDutyPolicy extends BaseModel {
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Repeat Policy If No One Acknowledges",
|
||||
description: "Repeat the policy if no one acknowledges the alert",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
nullable: false,
|
||||
@@ -457,6 +460,7 @@ export default class OnCallDutyPolicy extends BaseModel {
|
||||
title: "Repeat Policy Times If No One Acknowledges",
|
||||
description:
|
||||
"Repeat the policy X number of times if no one acknowledges the alert",
|
||||
defaultValue: 0,
|
||||
})
|
||||
@Column({
|
||||
nullable: false,
|
||||
|
||||
@@ -297,6 +297,7 @@ export default class OnCallDutyPolicyCustomField extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -335,6 +335,7 @@ export default class OnCallDutyPolicyEscalationRule extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -401,6 +401,7 @@ export default class OnCallDutyPolicyEscalationRuleSchedule extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -400,6 +400,7 @@ export default class OnCallDutyPolicyEscalationRuleTeam extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -53,7 +53,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
@TableMetadata({
|
||||
tableName: "OnCallDutyPolicyEscalationRuleUser",
|
||||
singularName: "User's On-Call Duty Escalation Rule",
|
||||
pluralName: "User's On-Call Duty Esdcalation Rules",
|
||||
pluralName: "User's On-Call Duty Escalation Rules",
|
||||
icon: IconProp.Call,
|
||||
tableDescription:
|
||||
"Manage on-call duty escalation rule for the on-call policy.",
|
||||
@@ -399,6 +399,7 @@ export default class OnCallDutyPolicyEscalationRuleUser extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -493,6 +493,7 @@ export default class OnCallDutyPolicyExecutionLog extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@@ -847,6 +848,7 @@ export default class OnCallDutyPolicyExecutionLog extends BaseModel {
|
||||
canReadOnRelationQuery: true,
|
||||
title: "On-Call Policy Execution Repeat Count",
|
||||
description: "How many times did we execute this on-call policy?",
|
||||
defaultValue: 1,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Number,
|
||||
|
||||
@@ -51,6 +51,9 @@ import Alert from "./Alert";
|
||||
@Entity({
|
||||
name: "OnCallDutyPolicyExecutionLogTimeline",
|
||||
})
|
||||
@Index(["onCallDutyPolicyExecutionLogId", "createdAt"])
|
||||
@Index(["projectId", "createdAt"])
|
||||
@Index(["alertSentToUserId", "projectId"])
|
||||
@TableMetadata({
|
||||
tableName: "OnCallDutyPolicyExecutionLogTimeline",
|
||||
singularName: "On-Call Duty Execution Log Timeline",
|
||||
@@ -701,6 +704,7 @@ export default class OnCallDutyPolicyExecutionLogTimeline extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
@@ -282,6 +282,7 @@ export default class OnCallDutyPolicyFeed extends BaseModel {
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user