@synoikia/core 0.9.0 → 0.10.1
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/dist/approvals/links.d.ts +1 -1
- package/dist/approvals/links.js +1 -1
- package/dist/approvals/links.js.map +1 -1
- package/dist/approvals/service.d.ts +6 -3
- package/dist/approvals/service.js +1 -4
- package/dist/approvals/service.js.map +1 -1
- package/dist/audit-query.d.ts +1 -0
- package/dist/audit-query.js +17 -11
- package/dist/audit-query.js.map +1 -1
- package/dist/auth/external-cloudflare.d.ts +11 -0
- package/dist/auth/external-cloudflare.js +76 -0
- package/dist/auth/external-cloudflare.js.map +1 -0
- package/dist/auth/external.d.ts +24 -0
- package/dist/auth/external.js +12 -0
- package/dist/auth/external.js.map +1 -0
- package/dist/auth/mcp-auth.d.ts +5 -19
- package/dist/auth/mcp-auth.js +60 -119
- package/dist/auth/mcp-auth.js.map +1 -1
- package/dist/auth/oauth.d.ts +1 -1
- package/dist/auth/oidc.d.ts +18 -13
- package/dist/auth/oidc.js +38 -6
- package/dist/auth/oidc.js.map +1 -1
- package/dist/auth/sessions.d.ts +0 -6
- package/dist/auth/sessions.js +0 -15
- package/dist/auth/sessions.js.map +1 -1
- package/dist/catalog/rules.d.ts +18 -18
- package/dist/config/env.d.ts +1 -1
- package/dist/db/schema.d.ts +8 -8
- package/dist/db/schema.js +2 -2
- package/dist/db/schema.js.map +1 -1
- package/dist/gate/pipeline.js +2 -0
- package/dist/gate/pipeline.js.map +1 -1
- package/dist/http/admin/auth.js +7 -7
- package/dist/http/admin/auth.js.map +1 -1
- package/dist/http/admin/instances.js +11 -7
- package/dist/http/admin/instances.js.map +1 -1
- package/dist/http/admin/system.js +3 -3
- package/dist/http/admin/system.js.map +1 -1
- package/dist/http/mcp/approval-routes.d.ts +2 -2
- package/dist/http/mcp/approval-routes.js +54 -46
- package/dist/http/mcp/approval-routes.js.map +1 -1
- package/dist/http/mcp/endpoint.js +5 -2
- package/dist/http/mcp/endpoint.js.map +1 -1
- package/dist/http/mcp/oauth-routes.d.ts +4 -2
- package/dist/http/mcp/oauth-routes.js +16 -8
- package/dist/http/mcp/oauth-routes.js.map +1 -1
- package/dist/http/mcp/pages.d.ts +2 -2
- package/dist/http/mcp/pages.js +4 -13
- package/dist/http/mcp/pages.js.map +1 -1
- package/dist/instances/manager.d.ts +16 -11
- package/dist/instances/manager.js +27 -11
- package/dist/instances/manager.js.map +1 -1
- package/dist/maintenance.js +1 -1
- package/dist/maintenance.js.map +1 -1
- package/dist/notify/service.d.ts +2 -2
- package/dist/settings.d.ts +10 -7
- package/dist/settings.js +59 -11
- package/dist/settings.js.map +1 -1
- package/drizzle/0016_client_auth_methods.sql +55 -0
- package/drizzle/meta/0016_snapshot.json +2848 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
package/dist/settings.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { eq } from 'drizzle-orm';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { writeAudit } from './audit.js';
|
|
4
|
+
import { EXTERNAL_PROVIDER_IDS, externalProvider } from './auth/external.js';
|
|
4
5
|
import { settings } from './db/schema.js';
|
|
5
6
|
import { ValidationError } from './errors.js';
|
|
6
|
-
import { cleanStored
|
|
7
|
+
import { cleanStored } from './lenient.js';
|
|
7
8
|
/** Global settings (design §8.2 "Settings"), one JSON document per section in the `settings` table. */
|
|
8
9
|
const SETTINGS_SCHEMAS = {
|
|
9
10
|
security: z
|
|
@@ -24,7 +25,7 @@ const SETTINGS_SCHEMAS = {
|
|
|
24
25
|
.min(1)
|
|
25
26
|
.max(24 * 30)
|
|
26
27
|
.default(12),
|
|
27
|
-
/** Approval-page sign-in on the MCP port (design §5.3):
|
|
28
|
+
/** Approval-page sign-in on the MCP port (design §5.3): how long one browser stays signed in. */
|
|
28
29
|
approvalSessionIdleHours: z
|
|
29
30
|
.number()
|
|
30
31
|
.int()
|
|
@@ -40,12 +41,18 @@ const SETTINGS_SCHEMAS = {
|
|
|
40
41
|
.prefault({}),
|
|
41
42
|
mcp: z
|
|
42
43
|
.object({
|
|
43
|
-
|
|
44
|
+
/** Client auth methods enabled on the MCP port (design §6.2); an endpoint can only narrow them. */
|
|
45
|
+
clientAuth: z
|
|
46
|
+
.object({
|
|
47
|
+
bearer: z.boolean().default(true),
|
|
48
|
+
oauth: z.boolean().default(true),
|
|
49
|
+
external: z.boolean().default(false),
|
|
50
|
+
})
|
|
51
|
+
.prefault({}),
|
|
52
|
+
external: z.object({ provider: z.enum(EXTERNAL_PROVIDER_IDS).default('cloudflare') }).prefault({}),
|
|
44
53
|
allowDynamicRegistration: z.boolean().default(true),
|
|
45
|
-
/** Cloudflare Access
|
|
54
|
+
/** The Cloudflare Access provider's application (design §6.2). */
|
|
46
55
|
cfAccess: z.object({ teamDomain: z.string().default(''), aud: z.string().default('') }).prefault({}),
|
|
47
|
-
/** Header set by an auth proxy (Authelia/Authentik) used only to attribute calls in `external` mode. */
|
|
48
|
-
trustedIdentityHeader: z.string().default(''),
|
|
49
56
|
accessTokenTtlMinutes: z
|
|
50
57
|
.number()
|
|
51
58
|
.int()
|
|
@@ -57,18 +64,47 @@ const SETTINGS_SCHEMAS = {
|
|
|
57
64
|
.prefault({}),
|
|
58
65
|
audit: z
|
|
59
66
|
.object({
|
|
60
|
-
/**
|
|
61
|
-
retentionDays: z.number().int().min(7).nullable().default(
|
|
67
|
+
/** Null = keep forever (design §10). */
|
|
68
|
+
retentionDays: z.number().int().min(7).nullable().default(90),
|
|
62
69
|
})
|
|
63
70
|
.prefault({}),
|
|
64
71
|
};
|
|
72
|
+
/** Rules across fields of `mcp`, checked on save only: stored values stay readable as they are. */
|
|
73
|
+
function mcpProblems(value) {
|
|
74
|
+
const problems = [];
|
|
75
|
+
if (!Object.values(value.clientAuth).some(Boolean))
|
|
76
|
+
problems.push('clientAuth: enable at least one method');
|
|
77
|
+
const provider = externalProvider(value);
|
|
78
|
+
if (value.clientAuth.external && !provider.configured(value))
|
|
79
|
+
problems.push(`external: configure ${provider.name} before you enable external auth`);
|
|
80
|
+
return problems;
|
|
81
|
+
}
|
|
65
82
|
export function isSettingsSection(name) {
|
|
66
83
|
return Object.prototype.hasOwnProperty.call(SETTINGS_SCHEMAS, name);
|
|
67
84
|
}
|
|
85
|
+
/** Stored fields that read as off, not as their open defaults, when they can't be read (design §6.2). */
|
|
86
|
+
const FAIL_CLOSED = {
|
|
87
|
+
mcp: { clientAuth: { bearer: false, oauth: false, external: false } },
|
|
88
|
+
};
|
|
89
|
+
/** Fields an earlier release stored that a save now refuses, so a stale client can't lose them silently. */
|
|
90
|
+
const RETIRED = {
|
|
91
|
+
mcp: ['defaultAuthMode', 'trustedIdentityHeader'],
|
|
92
|
+
};
|
|
93
|
+
const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
94
|
+
/** The lenient read of a stored section, with {@link FAIL_CLOSED} fields closed when dropped. */
|
|
95
|
+
function readStored(section, raw) {
|
|
96
|
+
const schema = SETTINGS_SCHEMAS[section];
|
|
97
|
+
const result = cleanStored(schema, raw, `settings.${section}`);
|
|
98
|
+
const closed = Object.entries(FAIL_CLOSED[section] ?? {}).filter(([key]) => result.dropped.some((p) => p === '*' || p === key || p.startsWith(`${key}.`)));
|
|
99
|
+
if (!closed.length)
|
|
100
|
+
return { ...result, value: result.value };
|
|
101
|
+
const cleaned = { ...(isPlainObject(result.cleaned) ? result.cleaned : {}), ...Object.fromEntries(closed) };
|
|
102
|
+
return { value: schema.parse(cleaned), cleaned, dropped: result.dropped };
|
|
103
|
+
}
|
|
68
104
|
/** Stored settings are read leniently: a field a newer schema rejects falls back to its default. */
|
|
69
105
|
export function getSettings(db, section) {
|
|
70
106
|
const row = db.select().from(settings).where(eq(settings.key, section)).get();
|
|
71
|
-
return
|
|
107
|
+
return readStored(section, row?.value).value;
|
|
72
108
|
}
|
|
73
109
|
/** Startup: removes stored settings fields the schema rejects, once; valid fields stay as stored. */
|
|
74
110
|
export function normalizeStoredSettings(db) {
|
|
@@ -76,7 +112,7 @@ export function normalizeStoredSettings(db) {
|
|
|
76
112
|
for (const row of db.select().from(settings).all()) {
|
|
77
113
|
if (!isSettingsSection(row.key))
|
|
78
114
|
continue;
|
|
79
|
-
const { cleaned, dropped } =
|
|
115
|
+
const { cleaned, dropped } = readStored(row.key, row.value);
|
|
80
116
|
if (!dropped.length)
|
|
81
117
|
continue;
|
|
82
118
|
db.update(settings).set({ value: cleaned }).where(eq(settings.key, row.key)).run();
|
|
@@ -86,10 +122,22 @@ export function normalizeStoredSettings(db) {
|
|
|
86
122
|
}
|
|
87
123
|
export function updateSettings(db, section, patch, actor = {}) {
|
|
88
124
|
const before = getSettings(db, section);
|
|
89
|
-
const
|
|
125
|
+
const retired = (RETIRED[section] ?? []).filter((k) => isPlainObject(patch) && k in patch);
|
|
126
|
+
if (retired.length)
|
|
127
|
+
throw new ValidationError('invalid_settings', 'Invalid settings', retired.map((k) => `${k}: no longer supported`));
|
|
128
|
+
// Nested objects merge with the stored ones, so a partial save keeps the fields it leaves out.
|
|
129
|
+
const merged = { ...before };
|
|
130
|
+
for (const [key, value] of Object.entries(isPlainObject(patch) ? patch : {})) {
|
|
131
|
+
const stored = merged[key];
|
|
132
|
+
merged[key] = isPlainObject(stored) && isPlainObject(value) ? { ...stored, ...value } : value;
|
|
133
|
+
}
|
|
134
|
+
const parsed = SETTINGS_SCHEMAS[section].safeParse(merged);
|
|
90
135
|
if (!parsed.success) {
|
|
91
136
|
throw new ValidationError('invalid_settings', 'Invalid settings', parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`));
|
|
92
137
|
}
|
|
138
|
+
const problems = section === 'mcp' ? mcpProblems(parsed.data) : [];
|
|
139
|
+
if (problems.length)
|
|
140
|
+
throw new ValidationError('invalid_settings', 'Invalid settings', problems);
|
|
93
141
|
db.transaction((tx) => {
|
|
94
142
|
tx.insert(settings)
|
|
95
143
|
.values({ key: section, value: parsed.data })
|
package/dist/settings.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
ALTER TABLE `plugin_instances` ADD `auth_methods` text;--> statement-breakpoint
|
|
2
|
+
-- The old auth modes become method lists, and nothing gains a method. External mode without Cloudflare Access
|
|
3
|
+
-- relied on the removed trusted header: it gets no method, so it refuses calls until an admin sets one.
|
|
4
|
+
CREATE TEMP TABLE `__client_auth_0016` AS
|
|
5
|
+
WITH `old` AS (
|
|
6
|
+
SELECT (SELECT CASE WHEN json_valid(`value`) THEN `value` END FROM `settings` WHERE `key` = 'mcp') AS `v`
|
|
7
|
+
), `base` AS (
|
|
8
|
+
SELECT
|
|
9
|
+
coalesce(json_extract(`v`, '$.cfAccess.teamDomain'), '') != ''
|
|
10
|
+
AND coalesce(json_extract(`v`, '$.cfAccess.aud'), '') != '' AS `cf`,
|
|
11
|
+
CASE WHEN json_extract(`v`, '$.defaultAuthMode') IN ('external', 'bearer', 'oauth', 'bearer+oauth')
|
|
12
|
+
THEN json_extract(`v`, '$.defaultAuthMode') ELSE 'bearer+oauth' END AS `d`
|
|
13
|
+
FROM `old`
|
|
14
|
+
)
|
|
15
|
+
SELECT `cf`, `d`,
|
|
16
|
+
`d` IN ('bearer', 'bearer+oauth') AS `d_bearer`,
|
|
17
|
+
`d` IN ('oauth', 'bearer+oauth') AS `d_oauth`,
|
|
18
|
+
`d` = 'external' AND `cf` AS `d_external`,
|
|
19
|
+
`d` IN ('bearer', 'bearer+oauth')
|
|
20
|
+
OR EXISTS (SELECT 1 FROM `plugin_instances` WHERE `auth_mode` IN ('bearer', 'bearer+oauth')) AS `g_bearer`,
|
|
21
|
+
`d` IN ('oauth', 'bearer+oauth')
|
|
22
|
+
OR EXISTS (SELECT 1 FROM `plugin_instances` WHERE `auth_mode` IN ('oauth', 'bearer+oauth')) AS `g_oauth`,
|
|
23
|
+
`cf` AND (`d` = 'external' OR EXISTS (SELECT 1 FROM `plugin_instances` WHERE `auth_mode` = 'external')) AS `g_external`
|
|
24
|
+
FROM `base`;--> statement-breakpoint
|
|
25
|
+
UPDATE `plugin_instances` SET `auth_methods` = CASE `auth_mode`
|
|
26
|
+
WHEN 'bearer' THEN '["bearer"]'
|
|
27
|
+
WHEN 'oauth' THEN '["oauth"]'
|
|
28
|
+
WHEN 'bearer+oauth' THEN '["bearer","oauth"]'
|
|
29
|
+
WHEN 'external' THEN CASE WHEN (SELECT `cf` FROM `__client_auth_0016`) THEN '["external"]' ELSE '[]' END
|
|
30
|
+
ELSE '[]' END
|
|
31
|
+
WHERE `auth_mode` IS NOT NULL;--> statement-breakpoint
|
|
32
|
+
-- An endpoint that inherited the old default keeps exactly its methods when the new global set is wider,
|
|
33
|
+
-- or when the old default gave it none.
|
|
34
|
+
UPDATE `plugin_instances` SET `auth_methods` = (
|
|
35
|
+
SELECT CASE `d`
|
|
36
|
+
WHEN 'bearer' THEN '["bearer"]'
|
|
37
|
+
WHEN 'oauth' THEN '["oauth"]'
|
|
38
|
+
WHEN 'bearer+oauth' THEN '["bearer","oauth"]'
|
|
39
|
+
ELSE CASE WHEN `cf` THEN '["external"]' ELSE '[]' END END
|
|
40
|
+
FROM `__client_auth_0016`)
|
|
41
|
+
WHERE `auth_mode` IS NULL AND (SELECT
|
|
42
|
+
(`g_bearer` AND NOT `d_bearer`) OR (`g_oauth` AND NOT `d_oauth`) OR (`g_external` AND NOT `d_external`)
|
|
43
|
+
OR NOT (`d_bearer` OR `d_oauth` OR `d_external`)
|
|
44
|
+
FROM `__client_auth_0016`);--> statement-breakpoint
|
|
45
|
+
-- The global methods are the old default and every endpoint's own mode, together.
|
|
46
|
+
UPDATE `settings` SET `value` = json_set(
|
|
47
|
+
json_remove(`value`, '$.defaultAuthMode', '$.trustedIdentityHeader'),
|
|
48
|
+
'$.clientAuth', (SELECT json_object(
|
|
49
|
+
'bearer', json(CASE WHEN `g_bearer` THEN 'true' ELSE 'false' END),
|
|
50
|
+
'oauth', json(CASE WHEN `g_oauth` THEN 'true' ELSE 'false' END),
|
|
51
|
+
'external', json(CASE WHEN `g_external` THEN 'true' ELSE 'false' END)) FROM `__client_auth_0016`),
|
|
52
|
+
'$.external', json_object('provider', 'cloudflare'))
|
|
53
|
+
WHERE `key` = 'mcp' AND json_valid(`value`);--> statement-breakpoint
|
|
54
|
+
DROP TABLE `__client_auth_0016`;--> statement-breakpoint
|
|
55
|
+
ALTER TABLE `plugin_instances` DROP COLUMN `auth_mode`;
|