underpost 3.2.30 → 3.2.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ghpkg.ci.yml +87 -0
- package/.github/workflows/npmpkg.ci.yml +9 -6
- package/.github/workflows/publish.ci.yml +3 -3
- package/.github/workflows/pwa-microservices-template-page.cd.yml +0 -7
- package/.github/workflows/release.cd.yml +1 -1
- package/CHANGELOG.md +1230 -971
- package/CLI-HELP.md +14 -6
- package/README.md +3 -3
- package/bin/build.js +40 -4
- package/bin/deploy.js +2 -2
- package/bump.config.js +1 -0
- package/docker-compose.yml +26 -26
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/package.json +15 -15
- package/scripts/disk-clean.sh +85 -60
- package/scripts/test-monitor.sh +1 -1
- package/src/api/core/core.controller.js +4 -65
- package/src/api/core/core.router.js +8 -14
- package/src/api/default/default.controller.js +2 -70
- package/src/api/default/default.router.js +7 -17
- package/src/api/document/document.controller.js +5 -77
- package/src/api/document/document.router.js +9 -13
- package/src/api/file/file.controller.js +9 -53
- package/src/api/file/file.router.js +14 -6
- package/src/api/test/test.controller.js +8 -53
- package/src/api/test/test.router.js +1 -4
- package/src/cli/cluster.js +104 -11
- package/src/cli/db.js +4 -2
- package/src/cli/deploy.js +60 -11
- package/src/cli/docker-compose.js +212 -1
- package/src/cli/fs.js +45 -25
- package/src/cli/image.js +147 -51
- package/src/cli/index.js +26 -6
- package/src/cli/release.js +50 -4
- package/src/cli/repository.js +98 -24
- package/src/cli/run.js +380 -178
- package/src/cli/secrets.js +75 -46
- package/src/cli/ssh.js +30 -11
- package/src/client/components/core/Modal.js +38 -4
- package/src/index.js +1 -1
- package/src/server/catalog.js +2 -0
- package/src/server/conf.js +163 -3
- package/src/server/downloader.js +3 -3
- package/src/server/middlewares.js +152 -0
package/scripts/disk-clean.sh
CHANGED
|
@@ -7,20 +7,20 @@ set -euo pipefail
|
|
|
7
7
|
|
|
8
8
|
VACUUM_SIZE="200M" # journalctl vacuum target
|
|
9
9
|
LARGE_LOG_SIZE="+100M" # threshold for truncation (find syntax)
|
|
10
|
-
TMP_AGE_DAYS=
|
|
11
|
-
CACHE_AGE_DAYS=
|
|
10
|
+
TMP_AGE_DAYS=1 # remove files older than this from /tmp and /var/tmp
|
|
11
|
+
CACHE_AGE_DAYS=5 # remove caches older than this from /var/cache
|
|
12
12
|
KEEP_KERNELS=2 # keep this many latest kernels
|
|
13
13
|
REMOVE_OPT=0 # ALWAYS allow removing /opt entries (user requested)
|
|
14
14
|
|
|
15
15
|
timestamp() { date +"%F %T"; }
|
|
16
16
|
log() {
|
|
17
|
-
|
|
17
|
+
echo "$(timestamp) $*"
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
# must be root
|
|
21
21
|
if [ "$EUID" -ne 0 ]; then
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
echo "This script must be run as root. Exiting."
|
|
23
|
+
exit 1
|
|
24
24
|
fi
|
|
25
25
|
|
|
26
26
|
log "=== Starting Rocky Linux 9 automated cleanup (batch mode) ==="
|
|
@@ -46,8 +46,8 @@ journalctl --vacuum-size="$VACUUM_SIZE"
|
|
|
46
46
|
# 3) Truncate very large logs in /var/log (safer than delete)
|
|
47
47
|
log "Truncating logs in /var/log larger than ${LARGE_LOG_SIZE} (keeps zero-sized file so services don't break)..."
|
|
48
48
|
find /var/log -type f -size "$LARGE_LOG_SIZE" -print0 2>/dev/null | while IFS= read -r -d '' f; do
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
echo "Truncating $f"
|
|
50
|
+
: > "$f" || echo "Failed to truncate $f"
|
|
51
51
|
done
|
|
52
52
|
|
|
53
53
|
# 4) Clean /tmp and /var/tmp older than TMP_AGE_DAYS
|
|
@@ -62,87 +62,110 @@ find /var/cache -mindepth 1 -mtime +"$CACHE_AGE_DAYS" -print0 2>/dev/null | xarg
|
|
|
62
62
|
# 6) Clean user caches (~/.cache) and Downloads older than CACHE_AGE_DAYS
|
|
63
63
|
log "Cleaning user caches and old downloads (home dirs)..."
|
|
64
64
|
for homedir in /home/* /root; do
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
65
|
+
[ -d "$homedir" ] || continue
|
|
66
|
+
usercache="$homedir/.cache"
|
|
67
|
+
userdownloads="$homedir/Downloads"
|
|
68
|
+
usertrash="$homedir/.local/share/Trash"
|
|
69
|
+
|
|
70
|
+
if [ -d "$usercache" ]; then
|
|
71
|
+
log "Removing contents of $usercache"
|
|
72
|
+
rm -rf "${usercache:?}/"* 2>/dev/null
|
|
73
|
+
fi
|
|
74
|
+
if [ -d "$userdownloads" ]; then
|
|
75
|
+
log "Removing files older than ${CACHE_AGE_DAYS} days from $userdownloads"
|
|
76
|
+
find "$userdownloads" -type f -mtime +"$CACHE_AGE_DAYS" -print0 2>/dev/null | xargs -0r rm -f -- 2>/dev/null
|
|
77
|
+
fi
|
|
78
|
+
if [ -d "$usertrash" ]; then
|
|
79
|
+
log "Emptying trash in $usertrash"
|
|
80
|
+
rm -rf "${usertrash:?}/"* 2>/dev/null
|
|
81
|
+
fi
|
|
82
82
|
done
|
|
83
83
|
|
|
84
|
-
# 7) Docker / Podman cleanup (if present)
|
|
84
|
+
# 7) Docker / Podman cleanup (if present) — this is what actually reclaims the
|
|
85
|
+
# overlay storage behind those duplicated `overlay` df lines.
|
|
85
86
|
if command -v docker >/dev/null 2>&1; then
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
log "Docker detected: pruning images/containers/volumes/build cache (aggressive)..."
|
|
88
|
+
docker system df || true
|
|
89
|
+
docker system prune -a --volumes -f || true
|
|
90
|
+
docker builder prune -a -f || true
|
|
89
91
|
fi
|
|
90
92
|
|
|
91
93
|
if command -v podman >/dev/null 2>&1; then
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
log "Podman detected: pruning images/containers/volumes (aggressive)..."
|
|
95
|
+
podman system df || true
|
|
96
|
+
podman system prune -a --volumes -f || true
|
|
95
97
|
fi
|
|
96
98
|
|
|
99
|
+
if command -v buildah >/dev/null 2>&1; then
|
|
100
|
+
log "Buildah detected: removing leftover working containers..."
|
|
101
|
+
buildah rm --all || true
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# 7b) Unmount leaked container overlay 'merged' mounts. Pruning frees the data
|
|
105
|
+
# but leaves these mountpoints attached, so they keep flooding `df -h` with
|
|
106
|
+
# identical `overlay ... /merged` rows. Only unmount overlays not backing a
|
|
107
|
+
# still-existing container, so running workloads are never disturbed.
|
|
108
|
+
log "Unmounting orphaned container overlay mounts..."
|
|
109
|
+
if command -v podman >/dev/null 2>&1; then
|
|
110
|
+
podman umount --all >/dev/null 2>&1 || true
|
|
111
|
+
fi
|
|
112
|
+
active_merged="$(podman ps -aq 2>/dev/null | xargs -r -I{} podman inspect --format '{{.GraphDriver.Data.MergedDir}}' {} 2>/dev/null || true)"
|
|
113
|
+
findmnt -rn -o TARGET 2>/dev/null | grep -E '/var/lib/(containers/storage|docker)/overlay.*/merged' | sort -r | while IFS= read -r m; do
|
|
114
|
+
if ! printf '%s\n' "$active_merged" | grep -qxF "$m"; then
|
|
115
|
+
echo "Unmounting orphaned overlay: $m"
|
|
116
|
+
umount -l "$m" 2>/dev/null || true
|
|
117
|
+
fi
|
|
118
|
+
done
|
|
119
|
+
|
|
97
120
|
# 8) Flatpak unused runtimes/apps (if present)
|
|
98
121
|
if command -v flatpak >/dev/null 2>&1; then
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
122
|
+
log "Flatpak detected: trying to uninstall unused runtimes/apps..."
|
|
123
|
+
flatpak uninstall --unused -y || flatpak uninstall --unused
|
|
124
|
+
flatpak repair
|
|
102
125
|
fi
|
|
103
126
|
|
|
104
127
|
# 9) Python Pip cleanup
|
|
105
128
|
if command -v pip3 >/dev/null 2>&1 || command -v pip >/dev/null 2>&1; then
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
129
|
+
log "Python Pip detected: cleaning cache..."
|
|
130
|
+
if command -v pip3 >/dev/null 2>&1; then
|
|
131
|
+
pip3 cache purge
|
|
132
|
+
elif command -v pip >/dev/null 2>&1; then
|
|
133
|
+
pip cache purge
|
|
134
|
+
fi
|
|
112
135
|
fi
|
|
113
136
|
|
|
114
137
|
# 10) Conda cleanup
|
|
115
138
|
if command -v conda >/dev/null 2>&1; then
|
|
116
|
-
|
|
117
|
-
|
|
139
|
+
log "Conda detected: cleaning all..."
|
|
140
|
+
conda clean --all -y
|
|
118
141
|
fi
|
|
119
142
|
|
|
120
143
|
# 11) Remove old kernels but keep the last KEEP_KERNELS (safe)
|
|
121
144
|
log "Removing old kernels, keeping the last $KEEP_KERNELS kernels..."
|
|
122
145
|
OLD_KERNELS=$(dnf repoquery --installonly --latest-limit=-$KEEP_KERNELS -q 2>/dev/null)
|
|
123
146
|
if [ -n "$OLD_KERNELS" ]; then
|
|
124
|
-
|
|
125
|
-
|
|
147
|
+
log "Old kernels to remove: $OLD_KERNELS"
|
|
148
|
+
dnf -y remove $OLD_KERNELS
|
|
126
149
|
else
|
|
127
|
-
|
|
150
|
+
log "No old kernels found by DNF repoquery. Only $KEEP_KERNELS or fewer are currently installed."
|
|
128
151
|
fi
|
|
129
152
|
|
|
130
153
|
# 12) /opt review and removal (ON by default now)
|
|
131
154
|
if [ -d /opt ]; then
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
155
|
+
log "/opt usage (top entries):"
|
|
156
|
+
du -sh /opt/* 2>/dev/null | sort -h | head -n 20
|
|
157
|
+
|
|
158
|
+
if [ "$REMOVE_OPT" = "1" ]; then
|
|
159
|
+
OPT_TARGETS=(/opt/local-path-provisioner)
|
|
160
|
+
for t in "${OPT_TARGETS[@]}"; do
|
|
161
|
+
if [ -d "$t" ]; then
|
|
162
|
+
log "Removing $t as REMOVE_OPT=1"
|
|
163
|
+
rm -rf "$t"
|
|
164
|
+
fi
|
|
165
|
+
done
|
|
166
|
+
else
|
|
167
|
+
log "Automatic /opt removals disabled (set REMOVE_OPT=1 to enable)."
|
|
168
|
+
fi
|
|
146
169
|
fi
|
|
147
170
|
|
|
148
171
|
# 13) Find large files > 100MB (report only)
|
|
@@ -150,8 +173,10 @@ log "Listing files larger than 100MB (report only):"
|
|
|
150
173
|
find / -xdev -type f -size +100M -printf '%s\t%p\n' 2>/dev/null | sort -nr | head -n 50 | awk '{printf "%.1fMB\t%s\n",$1/1024/1024,$2}'
|
|
151
174
|
|
|
152
175
|
# Final disk usage
|
|
153
|
-
log "Disk usage
|
|
176
|
+
log "Disk usage cleanup:"
|
|
154
177
|
df -h
|
|
178
|
+
log "Top-level usage ( / ):"
|
|
179
|
+
du -xh --max-depth=1 / | sort -rh | head -n 20
|
|
155
180
|
|
|
156
181
|
log "=== Cleanup finished ==="
|
|
157
182
|
exit 0
|
package/scripts/test-monitor.sh
CHANGED
|
@@ -24,7 +24,7 @@ MODE=runtime # runtime | instance
|
|
|
24
24
|
ENV=development # development | production
|
|
25
25
|
DEPLOY_ID=dd-test # deploy id (instance mode: parent of conf.instances.json)
|
|
26
26
|
INSTANCE_IDS= # instance mode: csv of ids (default: all in conf.instances.json)
|
|
27
|
-
IMAGE=underpost/wp:v3.2.
|
|
27
|
+
IMAGE=underpost/wp:v3.2.80 # runtime mode image (instance mode reads image from conf)
|
|
28
28
|
VERSIONS=green # csv of blue/green versions
|
|
29
29
|
REPLICAS=1 # replicas per deployment
|
|
30
30
|
NAMESPACE=default # k8s namespace
|
|
@@ -1,69 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildCrudController, serviceHandler } from '../../server/middlewares.js';
|
|
2
2
|
import { CoreService } from './core.service.js';
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
static post = async (req, res, options) => {
|
|
8
|
-
try {
|
|
9
|
-
const result = await CoreService.post(req, res, options);
|
|
10
|
-
return res.status(200).json({
|
|
11
|
-
status: 'success',
|
|
12
|
-
data: result,
|
|
13
|
-
});
|
|
14
|
-
} catch (error) {
|
|
15
|
-
logger.error(error, error.stack);
|
|
16
|
-
return res.status(400).json({
|
|
17
|
-
status: 'error',
|
|
18
|
-
message: error.message,
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
static get = async (req, res, options) => {
|
|
23
|
-
try {
|
|
24
|
-
const result = await CoreService.put(req, res, options);
|
|
25
|
-
return res.status(200).json({
|
|
26
|
-
status: 'success',
|
|
27
|
-
data: result,
|
|
28
|
-
});
|
|
29
|
-
} catch (error) {
|
|
30
|
-
logger.error(error, error.stack);
|
|
31
|
-
return res.status(400).json({
|
|
32
|
-
status: 'error',
|
|
33
|
-
message: error.message,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
static put = async (req, res, options) => {
|
|
38
|
-
try {
|
|
39
|
-
const result = await CoreService.get(req, res, options);
|
|
40
|
-
return res.status(200).json({
|
|
41
|
-
status: 'success',
|
|
42
|
-
data: result,
|
|
43
|
-
});
|
|
44
|
-
} catch (error) {
|
|
45
|
-
logger.error(error, error.stack);
|
|
46
|
-
return res.status(400).json({
|
|
47
|
-
status: 'error',
|
|
48
|
-
message: error.message,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
static delete = async (req, res, options) => {
|
|
53
|
-
try {
|
|
54
|
-
const result = await CoreService.delete(req, res, options);
|
|
55
|
-
return res.status(200).json({
|
|
56
|
-
status: 'success',
|
|
57
|
-
data: result,
|
|
58
|
-
});
|
|
59
|
-
} catch (error) {
|
|
60
|
-
logger.error(error, error.stack);
|
|
61
|
-
return res.status(400).json({
|
|
62
|
-
status: 'error',
|
|
63
|
-
message: error.message,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
}
|
|
4
|
+
const CoreController = buildCrudController(CoreService, {
|
|
5
|
+
get: serviceHandler(CoreService.get),
|
|
6
|
+
});
|
|
68
7
|
|
|
69
8
|
export { CoreController };
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { registerCrudRoutes } from '../../server/middlewares.js';
|
|
1
3
|
import { adminGuard } from '../../server/auth.js';
|
|
2
|
-
import { loggerFactory } from '../../server/logger.js';
|
|
3
4
|
import { CoreController } from './core.controller.js';
|
|
4
|
-
import express from 'express';
|
|
5
|
-
|
|
6
|
-
const logger = loggerFactory(import.meta);
|
|
7
5
|
|
|
8
6
|
class CoreRouter {
|
|
9
7
|
/**
|
|
@@ -11,16 +9,12 @@ class CoreRouter {
|
|
|
11
9
|
* @returns {import('express').Router}
|
|
12
10
|
*/
|
|
13
11
|
static router(options) {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
router.put(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
|
|
21
|
-
router.delete(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
|
|
22
|
-
router.delete(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
|
|
23
|
-
return router;
|
|
12
|
+
const adminOnly = [options.authMiddleware, adminGuard];
|
|
13
|
+
return registerCrudRoutes(express.Router(), CoreController, options, {
|
|
14
|
+
readGuards: adminOnly,
|
|
15
|
+
writeGuards: adminOnly,
|
|
16
|
+
deleteAllGuards: adminOnly,
|
|
17
|
+
});
|
|
24
18
|
}
|
|
25
19
|
}
|
|
26
20
|
|
|
@@ -1,74 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildCrudController } from '../../server/middlewares.js';
|
|
2
2
|
import { DefaultService } from './default.service.js';
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
class DefaultController {
|
|
7
|
-
static post = async (req, res, options) => {
|
|
8
|
-
try {
|
|
9
|
-
const result = await DefaultService.post(req, res, options);
|
|
10
|
-
return res.status(200).json({
|
|
11
|
-
status: 'success',
|
|
12
|
-
data: result,
|
|
13
|
-
});
|
|
14
|
-
} catch (error) {
|
|
15
|
-
logger.error(error, error.stack);
|
|
16
|
-
return res.status(400).json({
|
|
17
|
-
status: 'error',
|
|
18
|
-
message: error.message,
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
static get = async (req, res, options) => {
|
|
23
|
-
try {
|
|
24
|
-
const { page, limit } = req.query;
|
|
25
|
-
const result = await DefaultService.get(
|
|
26
|
-
{ ...req, query: { ...req.query, page: parseInt(page), limit: parseInt(limit) } },
|
|
27
|
-
res,
|
|
28
|
-
options,
|
|
29
|
-
);
|
|
30
|
-
return res.status(200).json({
|
|
31
|
-
status: 'success',
|
|
32
|
-
data: result,
|
|
33
|
-
});
|
|
34
|
-
} catch (error) {
|
|
35
|
-
logger.error(error, error.stack);
|
|
36
|
-
return res.status(400).json({
|
|
37
|
-
status: 'error',
|
|
38
|
-
message: error.message,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
static put = async (req, res, options) => {
|
|
43
|
-
try {
|
|
44
|
-
const result = await DefaultService.put(req, res, options);
|
|
45
|
-
return res.status(200).json({
|
|
46
|
-
status: 'success',
|
|
47
|
-
data: result,
|
|
48
|
-
});
|
|
49
|
-
} catch (error) {
|
|
50
|
-
logger.error(error, error.stack);
|
|
51
|
-
return res.status(400).json({
|
|
52
|
-
status: 'error',
|
|
53
|
-
message: error.message,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
static delete = async (req, res, options) => {
|
|
58
|
-
try {
|
|
59
|
-
const result = await DefaultService.delete(req, res, options);
|
|
60
|
-
return res.status(200).json({
|
|
61
|
-
status: 'success',
|
|
62
|
-
data: result,
|
|
63
|
-
});
|
|
64
|
-
} catch (error) {
|
|
65
|
-
logger.error(error, error.stack);
|
|
66
|
-
return res.status(400).json({
|
|
67
|
-
status: 'error',
|
|
68
|
-
message: error.message,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}
|
|
4
|
+
const DefaultController = buildCrudController(DefaultService);
|
|
73
5
|
|
|
74
6
|
export { DefaultController };
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { loggerFactory } from '../../server/logger.js';
|
|
2
|
-
import { DefaultController } from './default.controller.js';
|
|
3
1
|
import express from 'express';
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { registerCrudRoutes } from '../../server/middlewares.js';
|
|
3
|
+
import { DefaultController } from './default.controller.js';
|
|
6
4
|
|
|
7
5
|
class DefaultRouter {
|
|
8
6
|
/**
|
|
@@ -10,19 +8,11 @@ class DefaultRouter {
|
|
|
10
8
|
* @returns {import('express').Router}
|
|
11
9
|
*/
|
|
12
10
|
static router(options) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
async (req, res) => await DefaultController.get(req, res, options),
|
|
19
|
-
);
|
|
20
|
-
router.get(`/`, async (req, res) => await DefaultController.get(req, res, options));
|
|
21
|
-
router.put(`/:id`, async (req, res) => await DefaultController.put(req, res, options));
|
|
22
|
-
router.put(`/`, async (req, res) => await DefaultController.put(req, res, options));
|
|
23
|
-
router.delete(`/:id`, async (req, res) => await DefaultController.delete(req, res, options));
|
|
24
|
-
router.delete(`/`, async (req, res) => await DefaultController.delete(req, res, options));
|
|
25
|
-
return router;
|
|
11
|
+
// Fully unguarded (matches prior behavior).
|
|
12
|
+
return registerCrudRoutes(express.Router(), DefaultController, options, {
|
|
13
|
+
writeGuards: [],
|
|
14
|
+
deleteAllGuards: [],
|
|
15
|
+
});
|
|
26
16
|
}
|
|
27
17
|
}
|
|
28
18
|
|
|
@@ -1,81 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildCrudController, serviceHandler } from '../../server/middlewares.js';
|
|
2
2
|
import { DocumentService } from './document.service.js';
|
|
3
|
-
const logger = loggerFactory(import.meta);
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
status: 'success',
|
|
10
|
-
data: await DocumentService.post(req, res, options),
|
|
11
|
-
});
|
|
12
|
-
} catch (error) {
|
|
13
|
-
logger.error(error, error.stack);
|
|
14
|
-
return res.status(400).json({
|
|
15
|
-
status: 'error',
|
|
16
|
-
message: error.message,
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
static get = async (req, res, options) => {
|
|
21
|
-
try {
|
|
22
|
-
return res.status(200).json({
|
|
23
|
-
status: 'success',
|
|
24
|
-
data: await DocumentService.get(req, res, options),
|
|
25
|
-
});
|
|
26
|
-
} catch (error) {
|
|
27
|
-
logger.error(error, error.stack);
|
|
28
|
-
return res.status(400).json({
|
|
29
|
-
status: 'error',
|
|
30
|
-
message: error.message,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
static delete = async (req, res, options) => {
|
|
35
|
-
try {
|
|
36
|
-
const result = await DocumentService.delete(req, res, options);
|
|
37
|
-
return res.status(200).json({
|
|
38
|
-
status: 'success',
|
|
39
|
-
data: result,
|
|
40
|
-
});
|
|
41
|
-
} catch (error) {
|
|
42
|
-
logger.error(error, error.stack);
|
|
43
|
-
return res.status(400).json({
|
|
44
|
-
status: 'error',
|
|
45
|
-
message: error.message,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
static put = async (req, res, options) => {
|
|
50
|
-
try {
|
|
51
|
-
const result = await DocumentService.put(req, res, options);
|
|
52
|
-
return res.status(200).json({
|
|
53
|
-
status: 'success',
|
|
54
|
-
data: result,
|
|
55
|
-
});
|
|
56
|
-
} catch (error) {
|
|
57
|
-
logger.error(error, error.stack);
|
|
58
|
-
return res.status(400).json({
|
|
59
|
-
status: 'error',
|
|
60
|
-
message: error.message,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
static patch = async (req, res, options) => {
|
|
65
|
-
try {
|
|
66
|
-
const result = await DocumentService.patch(req, res, options);
|
|
67
|
-
return res.status(200).json({
|
|
68
|
-
status: 'success',
|
|
69
|
-
data: result,
|
|
70
|
-
});
|
|
71
|
-
} catch (error) {
|
|
72
|
-
logger.error(error, error.stack);
|
|
73
|
-
return res.status(400).json({
|
|
74
|
-
status: 'error',
|
|
75
|
-
message: error.message,
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
}
|
|
4
|
+
const DocumentController = buildCrudController(DocumentService, {
|
|
5
|
+
get: serviceHandler(DocumentService.get),
|
|
6
|
+
patch: serviceHandler(DocumentService.patch),
|
|
7
|
+
});
|
|
80
8
|
|
|
81
9
|
export { DocumentController };
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { loggerFactory } from '../../server/logger.js';
|
|
2
|
-
import { DocumentController } from './document.controller.js';
|
|
3
1
|
import express from 'express';
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { registerCrudRoutes } from '../../server/middlewares.js';
|
|
3
|
+
import { DocumentController } from './document.controller.js';
|
|
6
4
|
|
|
7
5
|
class DocumentRouter {
|
|
8
6
|
/**
|
|
@@ -11,23 +9,21 @@ class DocumentRouter {
|
|
|
11
9
|
*/
|
|
12
10
|
static router(options) {
|
|
13
11
|
const router = express.Router();
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const authOnly = [options.authMiddleware];
|
|
13
|
+
// Public listings — must come before the guarded generic /:id routes.
|
|
16
14
|
router.get(`/public/high`, async (req, res) => await DocumentController.get(req, res, options));
|
|
17
15
|
router.get(`/public`, async (req, res) => await DocumentController.get(req, res, options));
|
|
18
|
-
router.get(`/:id`, options.authMiddleware, async (req, res) => await DocumentController.get(req, res, options));
|
|
19
|
-
router.get(`/`, options.authMiddleware, async (req, res) => await DocumentController.get(req, res, options));
|
|
20
|
-
router.put(`/:id`, options.authMiddleware, async (req, res) => await DocumentController.put(req, res, options));
|
|
21
|
-
router.put(`/`, options.authMiddleware, async (req, res) => await DocumentController.put(req, res, options));
|
|
22
16
|
router.patch(`/:id/copy-share-link`, async (req, res) => await DocumentController.patch(req, res, options));
|
|
23
17
|
router.patch(
|
|
24
18
|
`/:id/toggle-public`,
|
|
25
19
|
options.authMiddleware,
|
|
26
20
|
async (req, res) => await DocumentController.patch(req, res, options),
|
|
27
21
|
);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
return registerCrudRoutes(router, DocumentController, options, {
|
|
23
|
+
readGuards: authOnly,
|
|
24
|
+
writeGuards: authOnly,
|
|
25
|
+
deleteAllGuards: authOnly,
|
|
26
|
+
});
|
|
31
27
|
}
|
|
32
28
|
}
|
|
33
29
|
|
|
@@ -1,59 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { controllerHandler, sendSuccess, serviceHandler, setCrossOriginHeaders } from '../../server/middlewares.js';
|
|
2
2
|
import { FileService } from './file.service.js';
|
|
3
|
-
const logger = loggerFactory(import.meta);
|
|
4
3
|
|
|
5
4
|
class FileController {
|
|
6
|
-
static post =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return res.status(400).json({
|
|
15
|
-
status: 'error',
|
|
16
|
-
message: error.message,
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
static get = async (req, res, options) => {
|
|
21
|
-
try {
|
|
22
|
-
if (req && req.headers && req.headers.origin) {
|
|
23
|
-
res.set('Access-Control-Allow-Origin', req.headers.origin);
|
|
24
|
-
} else res.setHeader('Access-Control-Allow-Origin', '*');
|
|
25
|
-
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
|
|
26
|
-
const result = await FileService.get(req, res, options);
|
|
27
|
-
if (result instanceof Buffer) {
|
|
28
|
-
return res.status(200).end(result);
|
|
29
|
-
}
|
|
30
|
-
return res.status(200).json({
|
|
31
|
-
status: 'success',
|
|
32
|
-
data: result,
|
|
33
|
-
});
|
|
34
|
-
} catch (error) {
|
|
35
|
-
logger.error(error, error.stack);
|
|
36
|
-
return res.status(400).json({
|
|
37
|
-
status: 'error',
|
|
38
|
-
message: error.message,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
static delete = async (req, res, options) => {
|
|
43
|
-
try {
|
|
44
|
-
const result = await FileService.delete(req, res, options);
|
|
45
|
-
return res.status(200).json({
|
|
46
|
-
status: 'success',
|
|
47
|
-
data: result,
|
|
48
|
-
});
|
|
49
|
-
} catch (error) {
|
|
50
|
-
logger.error(error, error.stack);
|
|
51
|
-
return res.status(400).json({
|
|
52
|
-
status: 'error',
|
|
53
|
-
message: error.message,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
};
|
|
5
|
+
static post = serviceHandler(FileService.post);
|
|
6
|
+
static get = controllerHandler(async (req, res, options) => {
|
|
7
|
+
setCrossOriginHeaders(req, res);
|
|
8
|
+
const result = await FileService.get(req, res, options);
|
|
9
|
+
if (result instanceof Buffer) return res.status(200).end(result);
|
|
10
|
+
return sendSuccess(res, result);
|
|
11
|
+
});
|
|
12
|
+
static delete = serviceHandler(FileService.delete);
|
|
57
13
|
}
|
|
58
14
|
|
|
59
15
|
export { FileController };
|