miolo 3.0.0-beta.21 → 3.0.0-beta.210
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/bin/build/build.mjs +53 -0
- package/bin/build/build_bin.mjs +17 -0
- package/bin/build/cli/client.mjs +52 -0
- package/bin/build/cli/css.mjs +22 -0
- package/bin/build/cli/index.mjs +40 -0
- package/bin/build/cli/ssr.mjs +21 -0
- package/bin/build/server/aliases.mjs +112 -0
- package/bin/build/server/babel.config.js +24 -0
- package/bin/build/server/banner.mjs +20 -0
- package/bin/build/server/bundle.mjs +111 -0
- package/bin/build/server/fix.mjs +15 -0
- package/bin/build/server/index.mjs +69 -0
- package/bin/build/server/options.mjs +83 -0
- package/bin/create/auth.mjs +23 -0
- package/bin/create/copy.mjs +175 -0
- package/bin/create/docker.mjs +25 -0
- package/bin/create/index.mjs +137 -0
- package/bin/create/pkgjson.mjs +72 -0
- package/bin/create/prepare-template.mjs +158 -0
- package/bin/create/validation.mjs +27 -0
- package/bin/dev/dev.mjs +32 -23
- package/bin/dev/dev_start.mjs +6 -5
- package/bin/index.mjs +94 -52
- package/bin/prod-bin/create-bin.mjs +42 -27
- package/bin/prod-bin/run.mjs +13 -9
- package/bin/{prod-run → run}/pid.mjs +4 -4
- package/bin/run/restart.mjs +13 -0
- package/bin/run/start.mjs +18 -0
- package/bin/run/stop.mjs +20 -0
- package/bin/util.mjs +35 -11
- package/package.json +59 -39
- package/src/config/.env +34 -12
- package/src/config/defaults.mjs +253 -185
- package/src/config/env.mjs +40 -22
- package/src/config/index.mjs +19 -24
- package/src/config/util.mjs +25 -10
- package/src/db-conn.mjs +34 -0
- package/src/engines/cron/emails.mjs +10 -5
- package/src/engines/cron/index.mjs +45 -51
- package/src/engines/cron/init.mjs +16 -17
- package/src/engines/cron/ipsum.mjs +65 -60
- package/src/engines/cron/syscheck.mjs +30 -30
- package/src/engines/emailer/index.mjs +1 -2
- package/src/engines/emailer/queue.mjs +14 -20
- package/src/engines/emailer/transporter.mjs +86 -74
- package/src/engines/geoip/index.mjs +23 -28
- package/src/engines/http/index.mjs +26 -15
- package/src/engines/logger/buildErrorEmailBody.mjs +72 -0
- package/src/engines/logger/index.mjs +114 -122
- package/src/engines/logger/injectStackTrace.mjs +59 -0
- package/src/engines/logger/logger_mail.mjs +47 -61
- package/src/engines/logger/reopenTransportOnHupSignal.mjs +12 -13
- package/src/engines/parser/Parser.mjs +77 -60
- package/src/engines/parser/index.mjs +1 -1
- package/src/engines/schema/diffObjs.mjs +41 -0
- package/src/engines/schema/index.mjs +4 -0
- package/src/engines/schema/input.mjs +54 -0
- package/src/engines/schema/output.mjs +66 -0
- package/src/engines/socket/index.mjs +44 -46
- package/src/index.mjs +15 -10
- package/src/middleware/auth/basic.mjs +41 -40
- package/src/middleware/auth/custom.mjs +10 -13
- package/src/middleware/auth/guest.mjs +27 -27
- package/src/middleware/auth/passport/index.mjs +374 -0
- package/src/middleware/auth/passport/session/index.mjs +43 -0
- package/src/middleware/auth/{credentials → passport}/session/store.mjs +35 -15
- package/src/middleware/auth/passport/session/store_koa_redis.mjs +3 -0
- package/src/middleware/context/cache/index.mjs +78 -33
- package/src/middleware/context/cache/options.mjs +19 -21
- package/src/middleware/context/db.mjs +45 -20
- package/src/middleware/context/index.mjs +12 -12
- package/src/middleware/extra.mjs +4 -5
- package/src/middleware/http/body.mjs +25 -25
- package/src/middleware/http/catcher.mjs +81 -8
- package/src/middleware/http/custom_blacklist.mjs +19 -16
- package/src/middleware/http/headers.mjs +37 -34
- package/src/middleware/http/ratelimit.mjs +16 -23
- package/src/middleware/http/request.mjs +60 -65
- package/src/middleware/routes/catch_js_error.mjs +30 -23
- package/src/middleware/routes/robots.mjs +4 -7
- package/src/middleware/routes/router/crud/attachCrudRoutes.mjs +108 -90
- package/src/middleware/routes/router/crud/getCrudConfig.mjs +31 -55
- package/src/middleware/routes/router/defaults.mjs +6 -19
- package/src/middleware/routes/router/index.mjs +17 -21
- package/src/middleware/routes/router/queries/attachQueriesRoutes.mjs +227 -50
- package/src/middleware/routes/router/queries/getQueriesConfig.mjs +45 -55
- package/src/middleware/routes/router/utils.mjs +41 -26
- package/src/middleware/ssr/context.mjs +5 -7
- package/src/middleware/ssr/html.mjs +66 -43
- package/src/middleware/ssr/loader.mjs +11 -14
- package/src/middleware/ssr/ssr_render.mjs +39 -22
- package/src/middleware/static/index.mjs +33 -14
- package/src/middleware/vite/devserver.mjs +38 -22
- package/src/middleware/vite/watcher.mjs +12 -14
- package/src/server-cron.mjs +13 -8
- package/src/server-dev.mjs +13 -16
- package/src/server.mjs +49 -51
- package/template/.agent/skills/miolo-app-arch/SKILL.md +218 -0
- package/template/.agent/skills/miolo-auth/SKILL.md +450 -0
- package/template/.agent/skills/miolo-cli-router/SKILL.md +394 -0
- package/template/.agent/skills/miolo-database/SKILL.md +358 -0
- package/template/.agent/skills/miolo-react-patterns/SKILL.md +426 -0
- package/template/.agent/skills/miolo-routing/SKILL.md +326 -0
- package/template/.agent/skills/miolo-schemas/SKILL.md +329 -0
- package/template/.agent/skills/miolo-session-context/SKILL.md +397 -0
- package/template/.agent/skills/miolo-ssr/SKILL.md +433 -0
- package/template/.editorconfig +18 -0
- package/template/.env +120 -0
- package/template/biome.json +63 -0
- package/template/components.json +21 -0
- package/template/db/init.sh +89 -0
- package/template/db/sql/00_drop.sql +2 -0
- package/template/db/sql/01_users.sql +31 -0
- package/template/db/sql/02_todos.sql +20 -0
- package/template/docker/Dockerfile +13 -0
- package/template/docker/docker-compose.yaml +79 -0
- package/template/gitignore +42 -0
- package/template/jsconfig.json +18 -0
- package/template/package.json +88 -0
- package/template/postcss.config.js +9 -0
- package/template/src/cli/App.jsx +25 -0
- package/template/src/cli/components/JsonTreeViewer.jsx +128 -0
- package/template/src/cli/components/shadcn-io/spinner/index.jsx +232 -0
- package/template/src/cli/components/stepper.jsx +408 -0
- package/template/src/cli/components/ui/avatar.jsx +36 -0
- package/template/src/cli/components/ui/badge.jsx +31 -0
- package/template/src/cli/components/ui/breadcrumb.jsx +97 -0
- package/template/src/cli/components/ui/card.jsx +73 -0
- package/template/src/cli/components/ui/collapsible.jsx +16 -0
- package/template/src/cli/components/ui/dropdown-menu.jsx +179 -0
- package/template/src/cli/components/ui/field.jsx +217 -0
- package/template/src/cli/components/ui/input.jsx +19 -0
- package/template/src/cli/components/ui/label.jsx +17 -0
- package/template/src/cli/components/ui/pagination.jsx +99 -0
- package/template/src/cli/components/ui/patched/alert.jsx +56 -0
- package/template/src/cli/components/ui/patched/button.jsx +45 -0
- package/template/src/cli/components/ui/patched/dialog.jsx +114 -0
- package/template/src/cli/components/ui/patched/sidebar.jsx +660 -0
- package/template/src/cli/components/ui/select.jsx +141 -0
- package/template/src/cli/components/ui/separator.jsx +21 -0
- package/template/src/cli/components/ui/sheet.jsx +115 -0
- package/template/src/cli/components/ui/skeleton.jsx +13 -0
- package/template/src/cli/components/ui/sonner.jsx +22 -0
- package/template/src/cli/components/ui/switch.jsx +25 -0
- package/template/src/cli/components/ui/table.jsx +88 -0
- package/template/src/cli/components/ui/textarea.jsx +16 -0
- package/template/src/cli/components/ui/tooltip.jsx +45 -0
- package/template/src/cli/config/store_keys.mjs +2 -0
- package/template/src/cli/context/data/DataContext.jsx +5 -0
- package/template/src/cli/context/data/DataProvider.jsx +44 -0
- package/template/src/cli/context/data/useBreads.mjs +15 -0
- package/template/src/cli/context/data/useDataContext.mjs +4 -0
- package/template/src/cli/context/session/SessionContext.mjs +4 -0
- package/template/src/cli/context/session/SessionProvider.jsx +31 -0
- package/template/src/cli/context/session/makePermissioner.mjs +34 -0
- package/template/src/cli/context/session/useSessionContext.mjs +6 -0
- package/template/src/cli/context/theme/ThemeContext.mjs +4 -0
- package/template/src/cli/context/theme/ThemeProvider.jsx +49 -0
- package/template/src/cli/context/theme/useThemeContext.mjs +6 -0
- package/template/src/cli/context/ui/UIContext.jsx +5 -0
- package/template/src/cli/context/ui/UIProvider.jsx +16 -0
- package/template/src/cli/context/ui/useUIContext.mjs +4 -0
- package/template/src/cli/context/util.mjs +17 -0
- package/template/src/cli/entry-cli.jsx +33 -0
- package/template/src/cli/hooks/useIsMobile.mjs +19 -0
- package/template/src/cli/hooks/useStoragedState.mjs +63 -0
- package/template/src/cli/index.html +29 -0
- package/template/src/cli/layout/app-sidebar.jsx +25 -0
- package/template/src/cli/layout/main-layout.jsx +63 -0
- package/template/src/cli/layout/nav-last-todos.jsx +72 -0
- package/template/src/cli/layout/nav-main.jsx +39 -0
- package/template/src/cli/layout/nav-user.jsx +105 -0
- package/template/src/cli/layout/prop-switcher.jsx +93 -0
- package/template/src/cli/lib/utils.mjs +10 -0
- package/template/src/cli/pages/Index.jsx +13 -0
- package/template/src/cli/pages/IndexOffline.jsx +13 -0
- package/template/src/cli/pages/IndexOnline.jsx +18 -0
- package/template/src/cli/pages/dash/Dashboard.jsx +29 -0
- package/template/src/cli/pages/offline/Login.jsx +43 -0
- package/template/src/cli/pages/offline/LoginForm.jsx +115 -0
- package/template/src/cli/pages/security/Security.jsx +39 -0
- package/template/src/cli/pages/security/SecurityForm.jsx +106 -0
- package/template/src/cli/pages/todos/TodoActions.jsx +99 -0
- package/template/src/cli/pages/todos/TodoAdd.jsx +43 -0
- package/template/src/cli/pages/todos/TodoList.jsx +60 -0
- package/template/src/cli/pages/todos/Todos.jsx +23 -0
- package/template/src/cli/pages/todos/context/TodosContext.jsx +5 -0
- package/template/src/cli/pages/todos/context/TodosProvider.jsx +191 -0
- package/template/src/cli/pages/todos/context/useTodosContext.mjs +4 -0
- package/template/src/ns/models/Todo.mjs +29 -0
- package/template/src/ns/models/TodoList.mjs +8 -0
- package/template/src/ns/models/User.mjs +40 -0
- package/template/src/server/bot/check_today.mjs +10 -0
- package/template/src/server/io/cache/base.mjs +21 -0
- package/template/src/server/io/db/filter.mjs +92 -0
- package/template/src/server/io/db/todos/delete.mjs +29 -0
- package/template/src/server/io/db/todos/find.mjs +13 -0
- package/template/src/server/io/db/todos/read.mjs +83 -0
- package/template/src/server/io/db/todos/toggle.mjs +37 -0
- package/template/src/server/io/db/todos/upsave.mjs +32 -0
- package/template/src/server/io/db/triggers/user.mjs +13 -0
- package/template/src/server/io/db/users/auth.mjs +132 -0
- package/template/src/server/io/db/users/pwd.mjs +38 -0
- package/template/src/server/io/db/users/save.mjs +17 -0
- package/template/src/server/miolo/auth/basic.mjs +15 -0
- package/template/src/server/miolo/auth/guest.mjs +3 -0
- package/template/src/server/miolo/auth/passport.mjs +73 -0
- package/template/src/server/miolo/cache.mjs +11 -0
- package/template/src/server/miolo/cron/foo.mjs +7 -0
- package/template/src/server/miolo/cron/index.mjs +28 -0
- package/template/src/server/miolo/cron/invalidate.mjs +21 -0
- package/template/src/server/miolo/db.mjs +36 -0
- package/template/src/server/miolo/http.mjs +14 -0
- package/template/src/server/miolo/index.mjs +43 -0
- package/template/src/server/miolo/routes/crud.mjs +16 -0
- package/template/src/server/miolo/routes/index.mjs +8 -0
- package/template/src/server/miolo/ssr/entry-server.jsx +13 -0
- package/template/src/server/miolo/ssr/loader.mjs +18 -0
- package/template/src/server/routes/index.mjs +66 -0
- package/template/src/server/routes/todos/mod.mjs +52 -0
- package/template/src/server/routes/todos/read.mjs +45 -0
- package/template/src/server/routes/todos/special.mjs +47 -0
- package/template/src/server/routes/users/user.mjs +54 -0
- package/template/src/server/server.mjs +10 -0
- package/template/src/server/utils/crypt.mjs +38 -0
- package/template/src/server/utils/io.mjs +15 -0
- package/template/src/server/utils/pwdfor.mjs +25 -0
- package/template/src/server/utils/schema.mjs +22 -0
- package/template/src/static/img/default/profile.png +0 -0
- package/template/src/static/img/favicon.ico +0 -0
- package/template/src/static/img/miolo_logo.png +0 -0
- package/template/src/static/img/miolo_name.png +0 -0
- package/template/src/static/public/manifest.json +21 -0
- package/template/src/static/public/sw.js +79 -0
- package/template/src/static/style/globals.css +156 -0
- package/template/src/static/style/json-tree.css +54 -0
- package/template/src/static/style/skeleton.css +49 -0
- package/bin/prod-build/build-client.mjs +0 -67
- package/bin/prod-build/build-server.mjs +0 -58
- package/bin/prod-run/restart.mjs +0 -9
- package/bin/prod-run/start.mjs +0 -15
- package/bin/prod-run/stop.mjs +0 -20
- package/src/engines/logger/verify.mjs +0 -22
- package/src/middleware/auth/credentials/index.mjs +0 -151
- package/src/middleware/auth/credentials/session/index.mjs +0 -24
- package/src/middleware/auth/credentials/session/store_koa_redis.mjs +0 -3
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
|
|
2
1
|
function _miolo_cacher_options_merge(def, opt, logger) {
|
|
3
|
-
|
|
4
|
-
const redis_host = opt?.redis?.host || def?.redis?.host || process.env?.REDIS_HOST || '127.0.0.1'
|
|
2
|
+
const redis_host = opt?.redis?.host || def?.redis?.host || process.env?.REDIS_HOST || "127.0.0.1"
|
|
5
3
|
const redis_port = opt?.redis?.port || def?.redis?.port || process.env?.REDIS_PORT || 6379
|
|
6
4
|
|
|
7
|
-
const redis_username =
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const redis_username =
|
|
6
|
+
opt?.redis?.username || def?.redis?.username || process.env?.REDIS_USERNAME || ""
|
|
7
|
+
const redis_password =
|
|
8
|
+
opt?.redis?.password || def?.redis?.password || process.env?.REDIS_PASSWORD || ""
|
|
9
|
+
let redis_credentials = ""
|
|
10
10
|
if (redis_username) {
|
|
11
|
-
redis_credentials= `${redis_username}${redis_password ? `:${redis_password}
|
|
11
|
+
redis_credentials = `${redis_username}${redis_password ? `:${redis_password}` : ""}@`
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const redis_url =
|
|
14
|
+
const redis_url =
|
|
15
|
+
opt?.redis?.url || def?.redis?.url || `redis://${redis_credentials}${redis_host}:${redis_port}`
|
|
15
16
|
|
|
16
17
|
return {
|
|
17
18
|
type: opt?.type || def?.type,
|
|
@@ -20,47 +21,44 @@ function _miolo_cacher_options_merge(def, opt, logger) {
|
|
|
20
21
|
},
|
|
21
22
|
namespace: opt?.namespace || def?.namespace,
|
|
22
23
|
version: opt?.version || def?.version,
|
|
23
|
-
clean: opt?.clean===true || def?.clean===true,
|
|
24
|
+
clean: opt?.clean === true || def?.clean === true,
|
|
24
25
|
ttl: opt?.ttl || def?.ttl,
|
|
25
26
|
log: logger
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
export function miolo_cacher_options_for_fly(config, options, logger) {
|
|
31
|
+
const d = config.cache.default
|
|
32
|
+
|
|
33
|
+
return _miolo_cacher_options_merge(d, options, logger)
|
|
34
|
+
}
|
|
29
35
|
|
|
30
36
|
export function miolo_cacher_options_for_calustra(config, logger) {
|
|
31
|
-
|
|
32
37
|
const d = config.cache.default
|
|
33
38
|
const c = config.cache.calustra
|
|
34
39
|
|
|
35
40
|
return _miolo_cacher_options_merge(d, c, logger)
|
|
36
41
|
}
|
|
37
42
|
|
|
38
|
-
|
|
39
43
|
export function miolo_cacher_options_for_session(config, logger) {
|
|
40
|
-
|
|
41
44
|
const d = config.cache.default
|
|
42
45
|
const s = config.cache.session
|
|
43
46
|
|
|
44
47
|
return _miolo_cacher_options_merge(d, s, logger)
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
|
|
48
50
|
export function miolo_cacher_options_for_custom(config, logger) {
|
|
49
|
-
|
|
50
51
|
const d = config.cache.default
|
|
51
52
|
const cs = config.cache.custom || {}
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
const custom = {}
|
|
54
55
|
|
|
55
|
-
for(const [name, c] of Object.entries(cs)) {
|
|
56
|
-
|
|
57
|
-
let opt = _miolo_cacher_options_merge(d, c, logger)
|
|
56
|
+
for (const [name, c] of Object.entries(cs)) {
|
|
57
|
+
const opt = _miolo_cacher_options_merge(d, c, logger)
|
|
58
58
|
opt.namespace = opt.namespace || `miolo-${name}`
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
custom[name] = opt
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
return custom
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
|
|
@@ -1,20 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
getConnection as miolo_db_connection_pg,
|
|
3
|
+
dropConnections as miolo_db_drop_connections_pg
|
|
4
|
+
} from "calustra/conn-postgres"
|
|
5
|
+
// import { getConnection as miolo_db_connection_sqlite, dropConnections as miolo_db_drop_connections_sqlite } from 'calustra/conn-sqlite'
|
|
6
|
+
import { miolo_cacher_options_for_calustra } from "./cache/options.mjs"
|
|
5
7
|
|
|
8
|
+
export function init_context_db(config, logger) {
|
|
6
9
|
const get_connection_wrap = async (options) => {
|
|
7
|
-
|
|
8
|
-
const dbOptions= {
|
|
10
|
+
const dbOptions = {
|
|
9
11
|
...config.db.options,
|
|
10
|
-
...options || {},
|
|
11
|
-
|
|
12
|
+
...(options || {}),
|
|
13
|
+
|
|
12
14
|
log: logger,
|
|
13
15
|
cache: miolo_cacher_options_for_calustra(config, logger)
|
|
14
16
|
}
|
|
15
|
-
|
|
16
17
|
|
|
17
|
-
let conn =
|
|
18
|
+
// let conn = undefined
|
|
19
|
+
// if (config.db.config.dialect === 'sqlite') {
|
|
20
|
+
// conn = await miolo_db_connection_sqlite(config.db.config, dbOptions)
|
|
21
|
+
// } else {
|
|
22
|
+
// conn = await miolo_db_connection_pg(config.db.config, dbOptions)
|
|
23
|
+
// }
|
|
24
|
+
|
|
25
|
+
const conn = await miolo_db_connection_pg(config.db.config, dbOptions)
|
|
26
|
+
if (config.db.config.dialect === "sqlite") {
|
|
27
|
+
logger.error(`[miolo] SQLite is not supported yet`)
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
conn.get_model = conn.getModel
|
|
19
31
|
|
|
20
32
|
// Maybe we need to force some conn is retrieved?
|
|
@@ -29,30 +41,43 @@ export function init_context_db (config, logger) {
|
|
|
29
41
|
}
|
|
30
42
|
|
|
31
43
|
const get_model_wrap = async (name, options) => {
|
|
32
|
-
|
|
33
|
-
const dbOptions= {
|
|
44
|
+
const dbOptions = {
|
|
34
45
|
...config.db.options,
|
|
35
|
-
...options || {},
|
|
46
|
+
...(options || {}),
|
|
36
47
|
log: logger
|
|
37
48
|
}
|
|
38
49
|
|
|
39
|
-
|
|
50
|
+
// let conn = undefined
|
|
51
|
+
// if (config.db.config.dialect === 'sqlite') {
|
|
52
|
+
// conn = await miolo_db_connection_sqlite(config.db.config, dbOptions)
|
|
53
|
+
// } else {
|
|
54
|
+
// conn = await miolo_db_connection_pg(config.db.config, dbOptions)
|
|
55
|
+
// }
|
|
56
|
+
|
|
57
|
+
const conn = await miolo_db_connection_pg(config.db.config, dbOptions)
|
|
58
|
+
if (config.db.config.dialect === "sqlite") {
|
|
59
|
+
logger.error(`[miolo] SQLite is not supported yet`)
|
|
60
|
+
}
|
|
61
|
+
|
|
40
62
|
return conn.get_model(name)
|
|
41
|
-
}
|
|
63
|
+
}
|
|
42
64
|
|
|
43
|
-
const db= {
|
|
65
|
+
const db = {
|
|
44
66
|
init_connection: async () => {
|
|
45
|
-
const conn = await get_connection_wrap({reset: true})
|
|
67
|
+
const conn = await get_connection_wrap({ reset: true })
|
|
46
68
|
return conn
|
|
47
69
|
},
|
|
48
70
|
fly_connection: async () => {
|
|
49
|
-
const conn = await get_connection_wrap({cache: false})
|
|
71
|
+
const conn = await get_connection_wrap({ cache: false })
|
|
50
72
|
return conn
|
|
51
73
|
},
|
|
52
74
|
get_connection: get_connection_wrap,
|
|
53
75
|
get_model: get_model_wrap,
|
|
54
|
-
drop_connections:
|
|
76
|
+
drop_connections: miolo_db_drop_connections_pg
|
|
77
|
+
// drop_connections: (config.db.config.dialect === 'sqlite')
|
|
78
|
+
// ? miolo_db_drop_connections_sqlite
|
|
79
|
+
// : miolo_db_drop_connections_pg
|
|
55
80
|
}
|
|
56
81
|
|
|
57
82
|
return db
|
|
58
|
-
}
|
|
83
|
+
}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { init_emailer_transporter } from
|
|
2
|
-
import { init_logger } from
|
|
3
|
-
import { init_parser } from
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { init_emailer_transporter } from "../../engines/emailer/index.mjs"
|
|
2
|
+
import { init_logger } from "../../engines/logger/index.mjs"
|
|
3
|
+
import { init_parser } from "../../engines/parser/index.mjs"
|
|
4
|
+
import { init_context_cache } from "./cache/index.mjs"
|
|
5
|
+
import { init_context_db } from "./db.mjs"
|
|
6
6
|
|
|
7
|
-
const init_context_middleware = (
|
|
7
|
+
const init_context_middleware = (app, config) => {
|
|
8
8
|
const emailer = init_emailer_transporter(config.mail)
|
|
9
9
|
const logger = init_logger(config.log, emailer, config?.name)
|
|
10
10
|
const parser = init_parser()
|
|
11
11
|
|
|
12
|
-
const db= init_context_db(config, logger)
|
|
12
|
+
const db = init_context_db(config, logger)
|
|
13
13
|
const cache = init_context_cache(config, logger)
|
|
14
14
|
|
|
15
15
|
// Assign miolo stuff to ctx
|
|
16
|
-
const mioloContext= {
|
|
17
|
-
config: {...config},
|
|
16
|
+
const mioloContext = {
|
|
17
|
+
config: { ...config },
|
|
18
18
|
emailer,
|
|
19
19
|
logger,
|
|
20
20
|
parser,
|
|
21
21
|
db,
|
|
22
22
|
cache
|
|
23
|
-
}
|
|
23
|
+
}
|
|
24
24
|
|
|
25
25
|
async function context_middleware(ctx, next) {
|
|
26
26
|
// Assign miolo stuff to ctx
|
|
27
|
-
ctx.miolo= mioloContext
|
|
27
|
+
ctx.miolo = mioloContext
|
|
28
28
|
await next()
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
app.use(context_middleware)
|
|
32
|
-
app.context.miolo= mioloContext
|
|
32
|
+
app.context.miolo = mioloContext
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export { init_context_middleware }
|
package/src/middleware/extra.mjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (middlewares==undefined || middlewares.length==0) {
|
|
1
|
+
const init_extra_middlewares = (app, middlewares) => {
|
|
2
|
+
if (middlewares === undefined || middlewares.length === 0) {
|
|
4
3
|
return
|
|
5
4
|
}
|
|
6
5
|
|
|
7
|
-
middlewares.
|
|
6
|
+
middlewares.forEach((midw) => {
|
|
8
7
|
app.use(midw)
|
|
9
8
|
})
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
export { init_extra_middlewares }
|
|
11
|
+
export { init_extra_middlewares }
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { constants } from "node:zlib"
|
|
2
|
+
import { bodyParser as koa_body_parser } from "@koa/bodyparser"
|
|
3
|
+
import koa_compress from "koa-compress"
|
|
4
4
|
|
|
5
|
-
const init_body_middleware = (
|
|
5
|
+
const init_body_middleware = (app) => {
|
|
6
6
|
// Compress
|
|
7
|
-
|
|
8
|
-
app.use(koa_compress({
|
|
9
|
-
filter: function (content_type) {
|
|
10
|
-
return content_type=='application/json' || content_type=='text/html'
|
|
11
|
-
},
|
|
12
|
-
//threshold: 2048,
|
|
13
|
-
gzip: {
|
|
14
|
-
flush: constants.Z_SYNC_FLUSH
|
|
15
|
-
},
|
|
16
|
-
deflate: {
|
|
17
|
-
flush: constants.Z_SYNC_FLUSH,
|
|
18
|
-
},
|
|
19
|
-
br: false // disable brotli
|
|
20
7
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
app.use(
|
|
9
|
+
koa_compress({
|
|
10
|
+
filter: (content_type) => content_type === "application/json" || content_type === "text/html",
|
|
11
|
+
//threshold: 2048,
|
|
12
|
+
gzip: {
|
|
13
|
+
flush: constants.Z_SYNC_FLUSH
|
|
14
|
+
},
|
|
15
|
+
deflate: {
|
|
16
|
+
flush: constants.Z_SYNC_FLUSH
|
|
17
|
+
},
|
|
18
|
+
br: false // disable brotli
|
|
19
|
+
})
|
|
20
|
+
)
|
|
28
21
|
|
|
22
|
+
app.use(
|
|
23
|
+
koa_body_parser({
|
|
24
|
+
formLimit: "100mb",
|
|
25
|
+
jsonLimit: "100mb",
|
|
26
|
+
bufferLimit: "100mb"
|
|
27
|
+
})
|
|
28
|
+
)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export { init_body_middleware }
|
|
31
|
+
export { init_body_middleware }
|
|
@@ -3,23 +3,95 @@
|
|
|
3
3
|
* @param ctx
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
|
|
6
|
+
import util from "node:util"
|
|
7
|
+
// import http from 'http'
|
|
8
|
+
import statuses from "statuses"
|
|
9
|
+
|
|
10
|
+
const _ONLY_WARN = [401, 403]
|
|
8
11
|
|
|
9
12
|
function init_catcher_middleware(app) {
|
|
10
|
-
const logger= app.context.miolo.logger
|
|
11
|
-
|
|
13
|
+
const logger = app.context.miolo.logger
|
|
14
|
+
|
|
12
15
|
async function catcher_middleware(err) {
|
|
16
|
+
// don't do anything if there is no error.
|
|
17
|
+
// this allows you to pass `this.onerror`
|
|
18
|
+
// to node-style callbacks.
|
|
19
|
+
if (err == null) return
|
|
20
|
+
|
|
21
|
+
// Ignore this error
|
|
22
|
+
// Appearing since Koa 3.1 + koa-static 6.x + koa-send 7.x
|
|
23
|
+
if (err.code === "ERR_STREAM_PREMATURE_CLOSE") return
|
|
24
|
+
|
|
25
|
+
// When dealing with cross-globals a normal `instanceof` check doesn't work properly.
|
|
26
|
+
// See https://github.com/koajs/koa/issues/1466
|
|
27
|
+
// We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
|
|
28
|
+
const isNativeError =
|
|
29
|
+
Object.prototype.toString.call(err) === "[object Error]" || err instanceof Error
|
|
30
|
+
if (!isNativeError) err = new Error(util.format("non-error thrown: %j", err))
|
|
31
|
+
|
|
32
|
+
let headerSent = false
|
|
33
|
+
if (this.headerSent || !this.writable) {
|
|
34
|
+
headerSent = err.headerSent = true
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// delegate
|
|
38
|
+
this.app.emit("error", err, this)
|
|
39
|
+
|
|
40
|
+
let statusCode = err.status || err.statusCode
|
|
41
|
+
// default to 500
|
|
42
|
+
if (typeof statusCode !== "number" || !statuses.message[statusCode]) statusCode = 500
|
|
43
|
+
|
|
44
|
+
// Log the error depending on the status
|
|
45
|
+
const ip = this.headers["x-real-ip"] || this.headers["x-orig-ip"] || this.ip || "127.0.0.1"
|
|
46
|
+
if (_ONLY_WARN.indexOf(statusCode) >= 0 || err.message.indexOf("Premature close") >= 0) {
|
|
47
|
+
logger.warn(`[${ip}] ${this.method} ${this.url} - ${statusCode}: ${err.message}`)
|
|
48
|
+
} else {
|
|
49
|
+
logger.error(`[${ip}] ${this.method} ${this.url} - ${statusCode}: ${err.message}`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// nothing we can do here other
|
|
53
|
+
// than delegate to the app-level
|
|
54
|
+
// handler and log.
|
|
55
|
+
if (headerSent) {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const { res } = this
|
|
60
|
+
|
|
61
|
+
// first unset all headers
|
|
62
|
+
/* istanbul ignore else */
|
|
63
|
+
if (typeof res.getHeaderNames === "function") {
|
|
64
|
+
res.getHeaderNames().forEach((name) => {
|
|
65
|
+
res.removeHeader(name)
|
|
66
|
+
})
|
|
67
|
+
} else {
|
|
68
|
+
res._headers = {} // Node < 7.7
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// then set those specified
|
|
72
|
+
this.set(err.headers)
|
|
73
|
+
|
|
74
|
+
// force text/plain
|
|
75
|
+
this.type = "text"
|
|
76
|
+
|
|
77
|
+
// respond
|
|
78
|
+
const code = statuses.message[statusCode]
|
|
79
|
+
const msg = err.expose ? err.message : code
|
|
80
|
+
this.status = err.status = statusCode
|
|
81
|
+
this.length = Buffer.byteLength(msg)
|
|
82
|
+
res.end(msg)
|
|
83
|
+
|
|
84
|
+
/*
|
|
13
85
|
if (!err) return
|
|
14
86
|
|
|
15
87
|
// wrap non-error object
|
|
16
|
-
|
|
88
|
+
const isNativeError = (Object.prototype.toString.call(err) === '[object Error]') || (err instanceof Error)
|
|
89
|
+
if (!isNativeError) {
|
|
17
90
|
let errMsg = err;
|
|
18
91
|
if (typeof err === 'object') {
|
|
19
92
|
try {
|
|
20
93
|
errMsg = JSON.stringify(err);
|
|
21
|
-
|
|
22
|
-
} catch (e) {}
|
|
94
|
+
} catch (_) {}
|
|
23
95
|
}
|
|
24
96
|
const newError = new Error('non-error thrown: ' + errMsg);
|
|
25
97
|
// err maybe an object, try to copy the name, message and stack to the new error instance
|
|
@@ -73,9 +145,10 @@ function init_catcher_middleware(app) {
|
|
|
73
145
|
this.body = JSON.stringify(this.body || '', null, 2)
|
|
74
146
|
this.length = Buffer.byteLength(this.body)
|
|
75
147
|
this.res.end(this.body)
|
|
148
|
+
*/
|
|
76
149
|
}
|
|
77
150
|
|
|
78
151
|
app.context.onerror = catcher_middleware
|
|
79
152
|
}
|
|
80
153
|
|
|
81
|
-
export {init_catcher_middleware}
|
|
154
|
+
export { init_catcher_middleware }
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
export const CUSTOM_BLACKLIST_IPS= [
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
export const CUSTOM_BLACKLIST_IPS = [
|
|
2
|
+
"52.212.247.108", // Amazon Data Services Ireland
|
|
3
|
+
"54.218.32.58", // Amazon.com, Inc. AMAZO-ZPDX4
|
|
4
|
+
"170.106.82.193", // Asia Pacific Network Information Centre (APNIC)
|
|
5
|
+
"110.166.71.39", // Asia Pacific Network Information Centre (APNIC)
|
|
6
|
+
"39.107.54.8", // Asia Pacific Network Information Centre (APNIC)
|
|
7
|
+
"205.210.31.240 ", // Palo Alto Networks, Inc (PAN-22)
|
|
8
|
+
"134.122.52.203", // DigitalOcean, LLC (DO-13)
|
|
9
|
+
"165.232.105.25", // DigitalOcean, LLC (DO-13)
|
|
10
|
+
"66.249.73.200", // Google
|
|
11
|
+
"35.206.153.204", // Google
|
|
12
|
+
"199.244.88.227", // Sundance International LLC (SIL-58)
|
|
13
|
+
"198.12.222.107", // GoDaddy.com, LLC (GODAD)
|
|
14
|
+
"212.128.118.10", // RIPE Network Coordination Centre (RIPE)
|
|
15
|
+
"103.218.240.46", // Asia Pacific Network Information Centre (APNIC)
|
|
16
|
+
"45.15.167.150", // ??
|
|
17
|
+
"165.227.173.41", // Frankfurt am Main, DE
|
|
18
|
+
"147.135.220.53", //
|
|
19
|
+
"47.237.23.78" // SG
|
|
17
20
|
]
|
|
@@ -1,73 +1,76 @@
|
|
|
1
|
-
import koa_cors from
|
|
2
|
-
import koa_proxy from
|
|
1
|
+
import koa_cors from "@koa/cors"
|
|
2
|
+
import koa_proxy from "koa-proxies"
|
|
3
3
|
|
|
4
4
|
const _if_options = (http, field, callback) => {
|
|
5
5
|
try {
|
|
6
|
-
const val= http[field]
|
|
7
|
-
if (
|
|
6
|
+
const val = http[field]
|
|
7
|
+
if (val !== undefined && val !== false) {
|
|
8
8
|
return callback(val)
|
|
9
9
|
}
|
|
10
|
-
} catch(_) {}
|
|
10
|
+
} catch (_) {}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const _cors_options = (options) => {
|
|
14
|
-
if (typeof options
|
|
14
|
+
if (typeof options === "object") {
|
|
15
15
|
return options
|
|
16
16
|
}
|
|
17
17
|
return {}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
21
20
|
const _proxy_options = (options) => {
|
|
22
|
-
if (options
|
|
23
|
-
options= {}
|
|
21
|
+
if (options === undefined) {
|
|
22
|
+
options = {}
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
const tpath= options?.path ||
|
|
25
|
+
const tpath = options?.path || "/"
|
|
27
26
|
|
|
28
27
|
const target = options?.target || "https://proxy.miolo.com"
|
|
29
|
-
const changeOrigin = options?.changeOrigin
|
|
30
|
-
const logs = options?.logs
|
|
31
|
-
|
|
28
|
+
const changeOrigin = options?.changeOrigin !== undefined ? options.changeOrigin : true
|
|
29
|
+
const logs = options?.logs !== undefined ? options.logs : true
|
|
32
30
|
|
|
33
|
-
const toptions= {
|
|
34
|
-
target,
|
|
31
|
+
const toptions = {
|
|
32
|
+
target,
|
|
33
|
+
changeOrigin,
|
|
34
|
+
logs
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
return [tpath, toptions]
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
const init_headers_middleware = (app, http) => {
|
|
41
|
+
const logger = app.context.miolo.logger
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const init_headers_middleware = ( app, http) => {
|
|
44
|
-
const logger= app.context.miolo.logger
|
|
45
|
-
|
|
46
|
-
_if_options(http, 'cors', (options) => {
|
|
47
|
-
if (options=='simple') {
|
|
43
|
+
_if_options(http, "cors", (options) => {
|
|
44
|
+
if (options === "simple") {
|
|
48
45
|
logger.debug(`[http] Setting CORS the simple way`)
|
|
49
46
|
app.use(async (ctx, next) => {
|
|
50
|
-
ctx.set(
|
|
51
|
-
ctx.set(
|
|
47
|
+
ctx.set("Access-Control-Allow-Origin", "*")
|
|
48
|
+
ctx.set("Access-Control-Expose-Headers", "SourceMap,X-SourceMap")
|
|
52
49
|
await next()
|
|
53
50
|
})
|
|
54
51
|
} else {
|
|
55
|
-
const coptions= _cors_options(options)
|
|
52
|
+
const coptions = _cors_options(options)
|
|
56
53
|
logger.debug(`[http] Setting CORS headers for ${JSON.stringify(coptions)}`)
|
|
57
54
|
app.use(koa_cors(coptions))
|
|
58
55
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
56
|
})
|
|
62
57
|
|
|
63
|
-
_if_options(http,
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
_if_options(http, "proxy", (options) => {
|
|
59
|
+
// Ensure NGINX is setting headers as:
|
|
60
|
+
// proxy_set_header Host $host;
|
|
61
|
+
// proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
62
|
+
// proxy_set_header X-Forwarded-Proto $scheme;
|
|
63
|
+
|
|
64
|
+
if (options === true) {
|
|
65
|
+
app.proxy = true
|
|
66
|
+
logger.debug(`[http] Setting Proxy to true`)
|
|
67
|
+
} else {
|
|
68
|
+
const [tpath, toptions] = _proxy_options(options)
|
|
69
|
+
logger.debug(`[http] Setting Proxy for ${tpath} to ${toptions.target} `)
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
})
|
|
71
|
+
app.use(koa_proxy(tpath, toptions))
|
|
72
|
+
}
|
|
73
|
+
})
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
export { init_headers_middleware }
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import ratelimit from
|
|
2
|
-
import {
|
|
3
|
-
import { ipsum_read_ips } from
|
|
4
|
-
import { CUSTOM_BLACKLIST_IPS } from
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import ratelimit from "koa-ratelimit"
|
|
2
|
+
import { magenta, yellow } from "tinguir"
|
|
3
|
+
import { ipsum_read_ips } from "../../engines/cron/ipsum.mjs"
|
|
4
|
+
import { CUSTOM_BLACKLIST_IPS } from "./custom_blacklist.mjs"
|
|
7
5
|
|
|
8
6
|
function init_rate_limit_middleware(app, config) {
|
|
9
|
-
|
|
10
|
-
const miolo= app.context.miolo
|
|
7
|
+
const miolo = app.context.miolo
|
|
11
8
|
|
|
12
9
|
//const _get_ip = (ctx) => ctx.headers["x-real-ip"] || ctx.headers["x-orig-ip"] || ctx.ip || '127.0.0.1'
|
|
13
10
|
|
|
@@ -16,23 +13,19 @@ function init_rate_limit_middleware(app, config) {
|
|
|
16
13
|
const _def_whitelist = (ctx) => {
|
|
17
14
|
const ips = config?.whitelist_ips || []
|
|
18
15
|
if (ips) {
|
|
19
|
-
return ips.indexOf(ctx.request.ip)>=0
|
|
16
|
+
return ips.indexOf(ctx.request.ip) >= 0
|
|
20
17
|
}
|
|
21
18
|
return false
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
const _def_blacklist = (ctx) => {
|
|
25
22
|
const ip = ctx.request.ip
|
|
26
|
-
const ips = [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
... config?.blacklist_ips || []
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
const doit = ips.indexOf(ip)>=0
|
|
23
|
+
const ips = [...ipsum_ips, ...CUSTOM_BLACKLIST_IPS, ...(config?.blacklist_ips || [])]
|
|
24
|
+
|
|
25
|
+
const doit = ips.indexOf(ip) >= 0
|
|
33
26
|
|
|
34
27
|
if (doit) {
|
|
35
|
-
ctx.miolo.logger.debug(`Rejecting ${yellow(
|
|
28
|
+
ctx.miolo.logger.debug(`Rejecting ${yellow("blacklisted")} ${magenta(ip)}`)
|
|
36
29
|
}
|
|
37
30
|
|
|
38
31
|
return doit
|
|
@@ -41,20 +34,20 @@ function init_rate_limit_middleware(app, config) {
|
|
|
41
34
|
const rateLimitDB = new Map()
|
|
42
35
|
|
|
43
36
|
const rateLimitConfig = {
|
|
44
|
-
driver:
|
|
37
|
+
driver: "memory",
|
|
45
38
|
db: rateLimitDB,
|
|
46
39
|
|
|
47
40
|
id: (ctx) => ctx.request.ip,
|
|
48
41
|
headers: {
|
|
49
|
-
remaining:
|
|
50
|
-
reset:
|
|
51
|
-
total:
|
|
42
|
+
remaining: "Rate-Limit-Remaining",
|
|
43
|
+
reset: "Rate-Limit-Reset",
|
|
44
|
+
total: "Rate-Limit-Total"
|
|
52
45
|
},
|
|
53
46
|
disableHeader: false,
|
|
54
47
|
|
|
55
48
|
max: config?.max || 1000,
|
|
56
49
|
duration: config?.duration || 60 * 1000,
|
|
57
|
-
errorMessage: config?.errorMessage ||
|
|
50
|
+
errorMessage: config?.errorMessage || "Rate Limit reached",
|
|
58
51
|
|
|
59
52
|
whitelist: config?.whitelist || _def_whitelist,
|
|
60
53
|
blacklist: config?.blacklist || _def_blacklist
|
|
@@ -63,4 +56,4 @@ function init_rate_limit_middleware(app, config) {
|
|
|
63
56
|
app.use(ratelimit(rateLimitConfig))
|
|
64
57
|
}
|
|
65
58
|
|
|
66
|
-
export {init_rate_limit_middleware}
|
|
59
|
+
export { init_rate_limit_middleware }
|