@selvajs/server 2.0.0-beta.18 → 2.0.0-beta.20
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/access/guards.d.ts +20 -3
- package/dist/access/guards.d.ts.map +1 -1
- package/dist/access/guards.js +44 -7
- package/dist/access/guards.js.map +1 -1
- package/dist/api/deps.d.ts +8 -1
- package/dist/api/deps.d.ts.map +1 -1
- package/dist/api/deps.js +2 -1
- package/dist/api/deps.js.map +1 -1
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/rate-limit.d.ts +6 -0
- package/dist/api/rate-limit.d.ts.map +1 -1
- package/dist/api/rate-limit.js +15 -0
- package/dist/api/rate-limit.js.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/settings.d.ts +2 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +261 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/handlers/me.d.ts.map +1 -1
- package/dist/handlers/me.js +4 -0
- package/dist/handlers/me.js.map +1 -1
- package/dist/handlers/projects.d.ts.map +1 -1
- package/dist/handlers/projects.js +14 -27
- package/dist/handlers/projects.js.map +1 -1
- package/dist/handlers/shareLinks.d.ts.map +1 -1
- package/dist/handlers/shareLinks.js +5 -2
- package/dist/handlers/shareLinks.js.map +1 -1
- package/dist/http/api-token.d.ts.map +1 -1
- package/dist/http/api-token.js +6 -2
- package/dist/http/api-token.js.map +1 -1
- package/dist/notifications/smtp-config.d.ts.map +1 -1
- package/dist/notifications/smtp-config.js +4 -2
- package/dist/notifications/smtp-config.js.map +1 -1
- package/dist/oauth/index.d.ts +8 -5
- package/dist/oauth/index.d.ts.map +1 -1
- package/dist/oauth/index.js +11 -5
- package/dist/oauth/index.js.map +1 -1
- package/dist/ops/deploymentConfig.d.ts +1 -0
- package/dist/ops/deploymentConfig.d.ts.map +1 -1
- package/dist/ops/deploymentConfig.js +15 -0
- package/dist/ops/deploymentConfig.js.map +1 -1
- package/dist/testing/harness.d.ts +2 -2
- package/dist/testing/harness.d.ts.map +1 -1
- package/dist/testing/harness.js +2 -1
- package/dist/testing/harness.js.map +1 -1
- package/dist/tokens/api-token-codec.d.ts +2 -2
- package/dist/tokens/api-token-codec.d.ts.map +1 -1
- package/dist/tokens/api-token-codec.js +7 -3
- package/dist/tokens/api-token-codec.js.map +1 -1
- package/dist/tokens/api-token-holder.d.ts +2 -0
- package/dist/tokens/api-token-holder.d.ts.map +1 -1
- package/dist/tokens/api-token-holder.js +18 -5
- package/dist/tokens/api-token-holder.js.map +1 -1
- package/dist/tokens/index.d.ts +1 -1
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +3 -3
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/token-codec.d.ts +23 -18
- package/dist/tokens/token-codec.d.ts.map +1 -1
- package/dist/tokens/token-codec.js +37 -24
- package/dist/tokens/token-codec.js.map +1 -1
- package/package.json +10 -5
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { composeManifest, defineSetting } from '@selvajs/platform/config';
|
|
2
|
+
import { DEFAULT_API_RATE_LIMIT } from '../api/rate-limit.js';
|
|
3
|
+
// Keys the engine reads, wherever the host app runs it. Providers declare their
|
|
4
|
+
// own (`@selvajs/*-provider/config`); the host app declares what only it reads.
|
|
5
|
+
const flag = (key, description, impact) => defineSetting({
|
|
6
|
+
key: `SELVA_FLAG_${key}`,
|
|
7
|
+
type: 'bool',
|
|
8
|
+
default: false,
|
|
9
|
+
onInvalid: 'fail',
|
|
10
|
+
class: 'setting',
|
|
11
|
+
description,
|
|
12
|
+
...(impact ? { impact } : {})
|
|
13
|
+
});
|
|
14
|
+
const tunableInt = (key, fallback, description, extra = {}) => defineSetting({
|
|
15
|
+
key,
|
|
16
|
+
type: 'int',
|
|
17
|
+
min: 1,
|
|
18
|
+
default: fallback,
|
|
19
|
+
onInvalid: 'default',
|
|
20
|
+
class: 'tunable',
|
|
21
|
+
description,
|
|
22
|
+
...extra
|
|
23
|
+
});
|
|
24
|
+
const MB = 1024 * 1024;
|
|
25
|
+
export const ENGINE_SETTINGS = composeManifest([
|
|
26
|
+
// ── Wiring ───────────────────────────────────────────────────────────────
|
|
27
|
+
...['AUTH', 'DATA', 'STORAGE'].map((slot) => defineSetting({
|
|
28
|
+
key: `SELVA_${slot}_PROVIDER`,
|
|
29
|
+
type: 'string',
|
|
30
|
+
default: 'local',
|
|
31
|
+
onInvalid: 'fail',
|
|
32
|
+
class: 'bootstrap',
|
|
33
|
+
summary: true,
|
|
34
|
+
description: `${slot.toLowerCase()} provider: local, supabase${slot === 'AUTH' ? ' or header' : ''}.`,
|
|
35
|
+
impact: 'Switching it does not move any data: the instance starts on what the new provider holds.'
|
|
36
|
+
})),
|
|
37
|
+
defineSetting({
|
|
38
|
+
key: 'SELVA_TENANCY',
|
|
39
|
+
type: 'enum',
|
|
40
|
+
values: ['single', 'multi'],
|
|
41
|
+
default: 'single',
|
|
42
|
+
onInvalid: 'fail',
|
|
43
|
+
class: 'bootstrap',
|
|
44
|
+
summary: true,
|
|
45
|
+
description: 'single: one org per deployment. multi: users create their own orgs.'
|
|
46
|
+
}),
|
|
47
|
+
defineSetting({
|
|
48
|
+
key: 'SELVA_CONFIG_PATH',
|
|
49
|
+
type: 'string',
|
|
50
|
+
onInvalid: 'fail',
|
|
51
|
+
class: 'bootstrap',
|
|
52
|
+
description: 'A selva.config.js that replaces env-driven provider wiring.'
|
|
53
|
+
}),
|
|
54
|
+
// ── Keys ─────────────────────────────────────────────────────────────────
|
|
55
|
+
defineSetting({
|
|
56
|
+
key: 'SELVA_HMAC_KEY',
|
|
57
|
+
type: 'string',
|
|
58
|
+
minLength: 32,
|
|
59
|
+
required: true,
|
|
60
|
+
onInvalid: 'fail',
|
|
61
|
+
class: 'secret',
|
|
62
|
+
sensitive: true,
|
|
63
|
+
generated: true,
|
|
64
|
+
summary: true,
|
|
65
|
+
description: 'Signs sessions (local auth), OAuth codes, MCP client ids and solve-event tokens.',
|
|
66
|
+
impact: 'Changing it without SELVA_HMAC_KEY_PREVIOUS breaks what it signed: run `selva keys rotate hmac`.'
|
|
67
|
+
}),
|
|
68
|
+
defineSetting({
|
|
69
|
+
key: 'SELVA_AT_REST_KEY',
|
|
70
|
+
type: 'key',
|
|
71
|
+
required: true,
|
|
72
|
+
onInvalid: 'fail',
|
|
73
|
+
class: 'secret',
|
|
74
|
+
sensitive: true,
|
|
75
|
+
generated: true,
|
|
76
|
+
summary: true,
|
|
77
|
+
description: 'Encrypts stored Rhino.Compute API keys.',
|
|
78
|
+
impact: 'Changing it without SELVA_AT_REST_KEY_PREVIOUS makes stored API keys unreadable: run `selva keys rotate at-rest`.'
|
|
79
|
+
}),
|
|
80
|
+
defineSetting({
|
|
81
|
+
key: 'SELVA_HMAC_KEY_PREVIOUS',
|
|
82
|
+
type: 'string',
|
|
83
|
+
minLength: 32,
|
|
84
|
+
onInvalid: 'fail',
|
|
85
|
+
class: 'secret',
|
|
86
|
+
sensitive: true,
|
|
87
|
+
generated: true,
|
|
88
|
+
summary: true,
|
|
89
|
+
description: 'The HMAC key before the last rotation. Still accepted for what it signed.',
|
|
90
|
+
impact: 'Removing it ends sessions, MCP clients and links signed before the rotation.'
|
|
91
|
+
}),
|
|
92
|
+
defineSetting({
|
|
93
|
+
key: 'SELVA_AT_REST_KEY_PREVIOUS',
|
|
94
|
+
type: 'key',
|
|
95
|
+
onInvalid: 'fail',
|
|
96
|
+
class: 'secret',
|
|
97
|
+
sensitive: true,
|
|
98
|
+
generated: true,
|
|
99
|
+
summary: true,
|
|
100
|
+
description: 'The encryption key before the last rotation. Stored API keys are re-sealed at boot.',
|
|
101
|
+
impact: 'Remove it only once /admin/system shows no API key on the previous key.'
|
|
102
|
+
}),
|
|
103
|
+
defineSetting({
|
|
104
|
+
key: 'SELVA_HMAC_KEY_PREVIOUS_EXPIRES',
|
|
105
|
+
type: 'string',
|
|
106
|
+
onInvalid: 'fail',
|
|
107
|
+
class: 'secret',
|
|
108
|
+
description: 'When SELVA_HMAC_KEY_PREVIOUS stops being accepted (ISO date). Set by `selva keys rotate`.',
|
|
109
|
+
impact: 'After it, anything only the previous key opens is refused. An unreadable date counts as passed.'
|
|
110
|
+
}),
|
|
111
|
+
defineSetting({
|
|
112
|
+
key: 'SELVA_AT_REST_KEY_PREVIOUS_EXPIRES',
|
|
113
|
+
type: 'string',
|
|
114
|
+
onInvalid: 'fail',
|
|
115
|
+
class: 'secret',
|
|
116
|
+
description: 'When SELVA_AT_REST_KEY_PREVIOUS stops being accepted (ISO date). Set by `selva keys rotate`.',
|
|
117
|
+
impact: 'After it, anything only the previous key opens is refused. An unreadable date counts as passed.'
|
|
118
|
+
}),
|
|
119
|
+
// ── Access ───────────────────────────────────────────────────────────────
|
|
120
|
+
defineSetting({
|
|
121
|
+
key: 'BOOTSTRAP_INSTANCE_ADMIN_EMAIL',
|
|
122
|
+
type: 'string',
|
|
123
|
+
onInvalid: 'fail',
|
|
124
|
+
class: 'bootstrap',
|
|
125
|
+
sensitive: true,
|
|
126
|
+
summary: true,
|
|
127
|
+
description: 'Only this address may claim instance admin while none exists. Break-glass recovery.'
|
|
128
|
+
}),
|
|
129
|
+
defineSetting({
|
|
130
|
+
key: 'SIGN_IN_MAX_AGE_DAYS',
|
|
131
|
+
type: 'int',
|
|
132
|
+
min: 0,
|
|
133
|
+
default: 0,
|
|
134
|
+
onInvalid: 'fail',
|
|
135
|
+
class: 'setting',
|
|
136
|
+
summary: true,
|
|
137
|
+
description: 'How long one sign-in at the identity provider lasts. 0 is off.',
|
|
138
|
+
impact: 'API tokens of anyone who has not signed in within this many days are revoked.'
|
|
139
|
+
}),
|
|
140
|
+
flag('ALLOW_ORG_CREATION', 'Self-service org creation (read by host apps).'),
|
|
141
|
+
flag('ALLOW_CROSS_ORG_PUBLIC', 'Public projects are visible to every signed-in user, not just the publishing org.', 'Turning it on widens who sees existing public projects.'),
|
|
142
|
+
flag('ALLOW_ORG_COMPUTE_OVERRIDE', 'Orgs may configure their own Rhino.Compute server.'),
|
|
143
|
+
flag('ENABLE_SHARING', 'Per-definition share links for anonymous access.', 'Turning it off stops every existing share link from resolving.'),
|
|
144
|
+
flag('ENABLE_PLATFORM_PROJECTS', 'Projects owned by instance admins and granted to orgs or users.'),
|
|
145
|
+
// ── Branding ─────────────────────────────────────────────────────────────
|
|
146
|
+
...[
|
|
147
|
+
['NAME', 'Product name in the header and titles.'],
|
|
148
|
+
['COPYRIGHT_NAME', 'Footer copyright owner. Defaults to the brand name.'],
|
|
149
|
+
['TAGLINE', 'Subtitle on the landing page.'],
|
|
150
|
+
['DESCRIPTION', 'Meta description for search and link previews.']
|
|
151
|
+
].map(([key, description]) => defineSetting({
|
|
152
|
+
key: `SELVA_BRAND_${key}`,
|
|
153
|
+
type: 'string',
|
|
154
|
+
onInvalid: 'fail',
|
|
155
|
+
class: 'setting',
|
|
156
|
+
description
|
|
157
|
+
})),
|
|
158
|
+
// ── Mail ─────────────────────────────────────────────────────────────────
|
|
159
|
+
defineSetting({
|
|
160
|
+
key: 'SMTP_HOST',
|
|
161
|
+
type: 'string',
|
|
162
|
+
onInvalid: 'fail',
|
|
163
|
+
class: 'setting',
|
|
164
|
+
description: 'SMTP server. Unset: invites return a link to send by hand.'
|
|
165
|
+
}),
|
|
166
|
+
defineSetting({
|
|
167
|
+
key: 'SMTP_PORT',
|
|
168
|
+
type: 'int',
|
|
169
|
+
min: 1,
|
|
170
|
+
max: 65535,
|
|
171
|
+
default: 587,
|
|
172
|
+
onInvalid: 'fail',
|
|
173
|
+
class: 'setting',
|
|
174
|
+
description: '587 for STARTTLS, 465 for implicit TLS.'
|
|
175
|
+
}),
|
|
176
|
+
defineSetting({
|
|
177
|
+
key: 'SMTP_USER',
|
|
178
|
+
type: 'string',
|
|
179
|
+
onInvalid: 'fail',
|
|
180
|
+
class: 'setting',
|
|
181
|
+
sensitive: true,
|
|
182
|
+
description: 'SMTP login.'
|
|
183
|
+
}),
|
|
184
|
+
defineSetting({
|
|
185
|
+
key: 'SMTP_PASS',
|
|
186
|
+
type: 'string',
|
|
187
|
+
onInvalid: 'fail',
|
|
188
|
+
class: 'secret',
|
|
189
|
+
sensitive: true,
|
|
190
|
+
description: 'SMTP password.'
|
|
191
|
+
}),
|
|
192
|
+
defineSetting({
|
|
193
|
+
key: 'SMTP_FROM',
|
|
194
|
+
type: 'string',
|
|
195
|
+
onInvalid: 'fail',
|
|
196
|
+
class: 'setting',
|
|
197
|
+
sensitive: true,
|
|
198
|
+
description: 'Sender address. Required once SMTP_HOST is set.'
|
|
199
|
+
}),
|
|
200
|
+
defineSetting({
|
|
201
|
+
key: 'SMTP_SECURE',
|
|
202
|
+
type: 'bool',
|
|
203
|
+
onInvalid: 'fail',
|
|
204
|
+
class: 'tunable',
|
|
205
|
+
description: 'Override the TLS mode inferred from the port.',
|
|
206
|
+
legacy: { bool: 'exact-true' }
|
|
207
|
+
}),
|
|
208
|
+
// ── Compute limits ───────────────────────────────────────────────────────
|
|
209
|
+
tunableInt('COMPUTE_SOLVE_DEADLINE_MS', 100_000, 'Longest one solve may run.', {
|
|
210
|
+
aliases: ['MAX_SOLVE_DURATION_MS'],
|
|
211
|
+
impact: 'Past the reverse proxy read timeout, solves fail there with a 502 instead.'
|
|
212
|
+
}),
|
|
213
|
+
tunableInt('COMPUTE_RATE_LIMIT_WINDOW_MS', 100_000, 'Compute rate-limit window.'),
|
|
214
|
+
tunableInt('COMPUTE_RATE_LIMIT_MAX', 120, 'Solves per user or share link per window.'),
|
|
215
|
+
tunableInt('MAX_DEFINITION_FILE_SIZE_BYTES', 50 * MB, 'Largest .gh upload.'),
|
|
216
|
+
tunableInt('MAX_IMAGE_FILE_SIZE_BYTES', 10 * MB, 'Largest cover image upload.'),
|
|
217
|
+
tunableInt('COMPUTE_REQUEST_MAX_BYTES', 256 * MB, 'Largest solve request body.', {
|
|
218
|
+
impact: 'Must stay at or below BODY_SIZE_LIMIT, or that limit rejects first.'
|
|
219
|
+
}),
|
|
220
|
+
tunableInt('COMPUTE_RESPONSE_MAX_BYTES', 300 * MB, 'Largest solve response body.'),
|
|
221
|
+
tunableInt('REMOTE_DEFINITION_FETCH_TIMEOUT_MS', 30_000, 'Deadline for fetching a remote .gh.'),
|
|
222
|
+
tunableInt('REMOTE_DEFINITION_CACHE_TTL_MS', 5 * 60 * 1000, 'How long remote .gh bytes stay cached.', {
|
|
223
|
+
aliases: ['DEFINITION_CACHE_TTL_MS']
|
|
224
|
+
}),
|
|
225
|
+
tunableInt('COMPUTE_MAX_QUEUE_DEPTH', 0, 'Solves allowed to wait per compute server. 0 is unbounded.', {
|
|
226
|
+
min: 0
|
|
227
|
+
}),
|
|
228
|
+
tunableInt('COMPUTE_QUEUE_WAIT_MS', 0, 'Longest a solve may wait queued. 0 is no deadline.', {
|
|
229
|
+
min: 0
|
|
230
|
+
}),
|
|
231
|
+
tunableInt('COMPUTE_DEFINITION_CACHE_MB', 256, 'Definition cache budget. 0 turns it off.', {
|
|
232
|
+
min: 0,
|
|
233
|
+
aliases: ['COMPUTE_DEFINITION_BYTE_CACHE_MB']
|
|
234
|
+
}),
|
|
235
|
+
tunableInt('COMPUTE_SOLVE_CACHE_MB', 256, 'Solve cache budget per warm compute server. 0 turns it off.', {
|
|
236
|
+
min: 0,
|
|
237
|
+
aliases: ['COMPUTE_RESPONSE_CACHE_MB']
|
|
238
|
+
}),
|
|
239
|
+
defineSetting({
|
|
240
|
+
key: 'COMPUTE_REUSE_DEFINITION_CACHE',
|
|
241
|
+
type: 'bool',
|
|
242
|
+
default: true,
|
|
243
|
+
onInvalid: 'default',
|
|
244
|
+
class: 'tunable',
|
|
245
|
+
description: 'Reuse the compute server’s cached definition instead of re-uploading it.',
|
|
246
|
+
impact: 'Leave on only with a compute server that reports a stale pointer (the VektorNode fork).'
|
|
247
|
+
}),
|
|
248
|
+
defineSetting({
|
|
249
|
+
key: 'COMPUTE_SERVER_CACHESOLVE',
|
|
250
|
+
type: 'bool',
|
|
251
|
+
default: true,
|
|
252
|
+
onInvalid: 'default',
|
|
253
|
+
class: 'tunable',
|
|
254
|
+
description: 'Ask Rhino.Compute to cache solve results server-side.'
|
|
255
|
+
}),
|
|
256
|
+
tunableInt('API_TOKEN_RATE_LIMIT_WINDOW_MS', DEFAULT_API_RATE_LIMIT.windowMs, 'API token rate-limit window.'),
|
|
257
|
+
tunableInt('API_TOKEN_RATE_LIMIT_MAX', DEFAULT_API_RATE_LIMIT.maxPerWindow, 'Requests per API token per window. 0 is off.', {
|
|
258
|
+
min: 0
|
|
259
|
+
})
|
|
260
|
+
]);
|
|
261
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/config/settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"me.d.ts","sourceRoot":"","sources":["../../src/handlers/me.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"me.d.ts","sourceRoot":"","sources":["../../src/handlers/me.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGjE,eAAO,MAAM,KAAK,EAAE,UAwBnB,CAAC"}
|
package/dist/handlers/me.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { formatApiScope } from '@selvajs/platform';
|
|
7
7
|
import { requireCaller } from '../api/index.js';
|
|
8
|
+
import { canCreateProjectIn } from '../access/index.js';
|
|
8
9
|
export const getMe = async (req) => {
|
|
9
10
|
const { ctx, user } = requireCaller(req);
|
|
10
11
|
return {
|
|
@@ -16,6 +17,9 @@ export const getMe = async (req) => {
|
|
|
16
17
|
platformPermissions: ctx.platformPermissions,
|
|
17
18
|
orgPermissions: ctx.orgPermissions,
|
|
18
19
|
starredDefinitions: req.profile?.starredDefinitions ?? [],
|
|
20
|
+
capabilities: {
|
|
21
|
+
createProjects: !!ctx.actingOrgId && (await canCreateProjectIn(req, ctx, ctx.actingOrgId))
|
|
22
|
+
},
|
|
19
23
|
...(ctx.apiScope && {
|
|
20
24
|
apiToken: {
|
|
21
25
|
id: ctx.apiScope.tokenId,
|
package/dist/handlers/me.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"me.js","sourceRoot":"","sources":["../../src/handlers/me.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"me.js","sourceRoot":"","sources":["../../src/handlers/me.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,CAAC,MAAM,KAAK,GAAe,KAAK,EAAE,GAAG,EAAE,EAAE;IAC9C,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAEzC,OAAO;QACN,IAAI,EAAE;YACL,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,GAAG,CAAC,OAAO,EAAE,WAAW;YACrC,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;YAC5C,cAAc,EAAE,GAAG,CAAC,cAAc;YAClC,kBAAkB,EAAE,GAAG,CAAC,OAAO,EAAE,kBAAkB,IAAI,EAAE;YACzD,YAAY,EAAE;gBACb,cAAc,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,MAAM,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;aAC1F;YACD,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI;gBACnB,QAAQ,EAAE;oBACT,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO;oBACxB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;oBAC/C,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS;iBACjC;aACD,CAAC;SACF;KACD,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/handlers/projects.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/handlers/projects.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAaN,KAAK,UAAU,EACf,MAAM,iBAAiB,CAAC;AAuBzB;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,UAgC1B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,UAuD3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,UAmCxB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,UAiD3B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,UAe3B,CAAC"}
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
* correct. The rest are lifted, logic intact, with reads moved onto `req.deps`.
|
|
8
8
|
*/
|
|
9
9
|
import { randomUUID } from 'node:crypto';
|
|
10
|
-
import { apiError, ApiErrorCode, collection, created, noContent, parseBody, parseListOptions, requireCaller, requireParams, CreateProjectBodySchema, UpdateProjectBodySchema } from '../api/index.js';
|
|
11
|
-
import {
|
|
10
|
+
import { apiError, ApiErrorCode, collection, created, defaultProjectCreateLimiter, noContent, parseBody, parseListOptions, requireCaller, requireParams, CreateProjectBodySchema, UpdateProjectBodySchema } from '../api/index.js';
|
|
11
|
+
import { canCreateDefinition, canEdit, canSolve, canView, slugify, SYSTEM_CONTEXT, outsideTokenOrg, scopeAllows, validateProjectFlags } from '@selvajs/platform';
|
|
12
12
|
import { resolveAccessibleProjects } from '../definitions/index.js';
|
|
13
|
-
import { projectAccessInputFromRowsWith, requireCanCreateProject, requireCanEditProjectSettings, requireCanManage } from '../access/index.js';
|
|
13
|
+
import { projectAccessInputFromRowsWith, requireCanCreateProject, requireCanEditProjectSettings, requireProjectVisibilityAllowed, requireCanManage } from '../access/index.js';
|
|
14
14
|
import { createProjectWithUniqueSlug, deleteProjectWithBlobs } from '../projects/index.js';
|
|
15
15
|
/**
|
|
16
16
|
* Projects the caller can view. `canCreateDefinitions` says whether
|
|
@@ -53,12 +53,16 @@ export const createProject = async (req) => {
|
|
|
53
53
|
// envelope. Guards stay shared with the page loads that need them.
|
|
54
54
|
await requireCanCreateProject(req, ctx.actingOrgId);
|
|
55
55
|
const input = await parseBody(req.request, CreateProjectBodySchema);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
await requireProjectVisibilityAllowed(req, ctx, ctx.actingOrgId, input);
|
|
57
|
+
if (ctx.apiScope) {
|
|
58
|
+
// Per owner, not per key: minting more keys mustn't buy more projects.
|
|
59
|
+
const limiter = req.deps.projectCreateLimiter === undefined
|
|
60
|
+
? defaultProjectCreateLimiter()
|
|
61
|
+
: req.deps.projectCreateLimiter;
|
|
62
|
+
const verdict = await limiter?.hit(`projects:user:${ctx.userId}`);
|
|
63
|
+
if (verdict && !verdict.allowed) {
|
|
64
|
+
apiError(429, ApiErrorCode.RATE_LIMITED, `Too many projects created with API tokens. Retry in ${verdict.retryAfter ?? 1}s.`, undefined, { retryAfter: String(verdict.retryAfter ?? 1) });
|
|
65
|
+
}
|
|
62
66
|
}
|
|
63
67
|
const autoJoinOnUpload = input.autoJoinOnUpload ?? false;
|
|
64
68
|
// Same call PATCH makes, rather than a second hand-rolled copy of the
|
|
@@ -129,24 +133,7 @@ export const updateProject = async (req) => {
|
|
|
129
133
|
// project's settings.
|
|
130
134
|
const { ctx, project: existing } = await requireCanEditProjectSettings(req, id);
|
|
131
135
|
const input = await parseBody(req.request, UpdateProjectBodySchema);
|
|
132
|
-
|
|
133
|
-
// see it, `canReclaim` returns false forever, and with
|
|
134
|
-
// ENABLE_PLATFORM_PROJECTS off (the default) every rule denies everyone,
|
|
135
|
-
// including admins. Escalating into it must be instance-admin only.
|
|
136
|
-
if (input.visibility === 'platform' && existing.visibility !== 'platform') {
|
|
137
|
-
if (!hasPermission(ctx, 'instance_admin')) {
|
|
138
|
-
apiError(403, ApiErrorCode.FORBIDDEN, 'Only a platform admin can give a project platform visibility.');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
// Flipping *to* public is a disclosure action — a stricter gate than a
|
|
142
|
-
// normal edit.
|
|
143
|
-
if (input.visibility === 'public' && existing.visibility !== 'public') {
|
|
144
|
-
const orgMember = await req.deps.orgs.getOrgMember(ctx, existing.orgId, ctx.userId);
|
|
145
|
-
const passes = withAdminBypass(ctx.platformPermissions, () => canChangeVisibilityToPublic({ orgMember }));
|
|
146
|
-
if (!passes) {
|
|
147
|
-
apiError(403, ApiErrorCode.FORBIDDEN, 'Only org owners or admins can make a project public.');
|
|
148
|
-
}
|
|
149
|
-
}
|
|
136
|
+
await requireProjectVisibilityAllowed(req, ctx, existing.orgId, input, existing);
|
|
150
137
|
// The flag/visibility invariant runs on the merged post-patch shape, so a
|
|
151
138
|
// partial update is validated against what the project will become.
|
|
152
139
|
const flagIssues = validateProjectFlags({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/handlers/projects.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,uBAAuB,EAEvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/handlers/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shareLinks.d.ts","sourceRoot":"","sources":["../../src/handlers/shareLinks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgBH,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"shareLinks.d.ts","sourceRoot":"","sources":["../../src/handlers/shareLinks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgBH,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,iBAAiB,CAAC;AA0B9D,eAAO,MAAM,cAAc,EAAE,UAU5B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,UAkC7B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,UAc7B,CAAC"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { randomUUID } from 'node:crypto';
|
|
14
14
|
import { apiError, ApiErrorCode, CreatedShareLinkResponseSchema, noContent, parseBody, parseListOptions, parseParam, requireCaller, shaped, shapedCollection, ShareLinkResponseSchema } from '../api/index.js';
|
|
15
|
-
import { CreateShareLinkInputSchema, DEFAULT_SHARE_LINK_MAX_SOLVES } from '@selvajs/platform';
|
|
15
|
+
import { CreateShareLinkInputSchema, DEFAULT_SHARE_LINK_MAX_SOLVES, DEFAULT_SHARE_LINK_TTL_DAYS } from '@selvajs/platform';
|
|
16
16
|
import { GuidSchema } from '@selvajs/platform/definitions';
|
|
17
17
|
import { requireEditableDefinition } from '../access/index.js';
|
|
18
18
|
import { tokenCodec } from './services.js';
|
|
@@ -51,7 +51,10 @@ export const createShareLink = async (req) => {
|
|
|
51
51
|
name: input.name,
|
|
52
52
|
createdBy: user.id,
|
|
53
53
|
createdAt: new Date().toISOString(),
|
|
54
|
-
|
|
54
|
+
// Same rule as maxSolves: absent gets the default, an explicit null never expires.
|
|
55
|
+
expiresAt: input.expiresAt === undefined
|
|
56
|
+
? new Date(Date.now() + DEFAULT_SHARE_LINK_TTL_DAYS * 86_400_000).toISOString()
|
|
57
|
+
: input.expiresAt,
|
|
55
58
|
revokedAt: null,
|
|
56
59
|
allowSolve: input.allowSolve,
|
|
57
60
|
// The default applies only when the field is absent. An explicit `null`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shareLinks.js","sourceRoot":"","sources":["../../src/handlers/shareLinks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,QAAQ,EACR,YAAY,EACZ,8BAA8B,EAC9B,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,MAAM,EACN,gBAAgB,EAChB,uBAAuB,EACvB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,
|
|
1
|
+
{"version":3,"file":"shareLinks.js","sourceRoot":"","sources":["../../src/handlers/shareLinks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../src/http/api-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,aAAa,EACb,OAAO,EACP,cAAc,EACd,UAAU,EACV,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAGN,KAAK,aAAa,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAoB,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../src/http/api-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,aAAa,EACb,OAAO,EACP,cAAc,EACd,UAAU,EACV,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAGN,KAAK,aAAa,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAoB,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAK5F,MAAM,MAAM,kBAAkB;AAC7B,2EAA2E;AACzE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE;AACtE,0EAA0E;GACxE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,mBAAmB;IACnC,8EAA8E;IAC9E,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,kBAAkB,CAAC,CAAC;IAC1D,IAAI,EAAE,IAAI,CACT,aAAa,EACb,WAAW,GAAG,MAAM,GAAG,aAAa,GAAG,UAAU,GAAG,uBAAuB,GAAG,aAAa,CAC3F,CAAC;IACF,qHAAqH;IACrH,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC;;;OAGG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,UAAU,KAAK,OAAO,CAAC;IAC3C;;;OAGG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qFAAqF;IACrF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,mBAAmB,EACzB,EAAE,UAAuB,EAAE,GAAE,sBAA2B,GACtD,OAAO,CAAC,kBAAkB,CAAC,CAqG7B;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,EAAE,UAAU,SAAS,GAAG,kBAAkB,CAoBhG;AAED,8FAA8F;AAC9F,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKxD"}
|
package/dist/http/api-token.js
CHANGED
|
@@ -2,6 +2,7 @@ import { SYSTEM_CONTEXT, narrowApiTokenContext } from '@selvajs/platform';
|
|
|
2
2
|
import { ApiErrorCode } from '../api/errors.js';
|
|
3
3
|
import { API_TOKEN_PREFIX, looksLikeApiToken } from '../tokens/api-token-codec.js';
|
|
4
4
|
import { canHoldApiTokens } from '../tokens/api-token-holder.js';
|
|
5
|
+
import { findByToken } from '../tokens/token-codec.js';
|
|
5
6
|
import { buildRequestContext } from './request-context.js';
|
|
6
7
|
import { signInIsStale } from './sign-in-age.js';
|
|
7
8
|
/** `lastUsedAt` is written at most this often per token, so a busy key isn't a write per request. */
|
|
@@ -68,7 +69,7 @@ export async function resolveApiToken(request, deps, { pathPrefix = '/api/v1/' }
|
|
|
68
69
|
return UNAVAILABLE;
|
|
69
70
|
if (!deps.codec.hasValidChecksum(raw))
|
|
70
71
|
return UNAUTHORIZED;
|
|
71
|
-
const token = await store.getByTokenHash(SYSTEM_CONTEXT,
|
|
72
|
+
const token = await findByToken(deps.codec, raw, (h) => store.getByTokenHash(SYSTEM_CONTEXT, h));
|
|
72
73
|
if (!token)
|
|
73
74
|
return UNAUTHORIZED;
|
|
74
75
|
const [user, member, platformPermissions] = await Promise.all([
|
|
@@ -94,7 +95,10 @@ export async function resolveApiToken(request, deps, { pathPrefix = '/api/v1/' }
|
|
|
94
95
|
return UNAUTHORIZED;
|
|
95
96
|
}
|
|
96
97
|
const live = await buildRequestContext({ user, platformPermissions, membership: member, pinOrg: true }, { orgs: deps.data.orgs });
|
|
97
|
-
|
|
98
|
+
// A key must always be able to revoke itself, or a refused holder couldn't
|
|
99
|
+
// sign out. Revoking reaches nothing else.
|
|
100
|
+
const revokingItself = request.method === 'DELETE' && url.pathname === `${pathPrefix.replace(/\/$/, '')}/me/token`;
|
|
101
|
+
if (!revokingItself && !deps.holderVerdicts?.passed(token.id, now)) {
|
|
98
102
|
const holds = await canHoldApiTokens(live, token.scopes, {
|
|
99
103
|
policy: deps.mayHoldApiTokens,
|
|
100
104
|
deps: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token.js","sourceRoot":"","sources":["../../src/http/api-token.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EACN,gBAAgB,EAChB,iBAAiB,EAEjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAA6B,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA6CjD,qGAAqG;AACrG,MAAM,2BAA2B,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAElD,MAAM,YAAY,GAAuB;IACxC,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,YAAY,CAAC,YAAY;IAC/B,OAAO,EAAE,gDAAgD;CACzD,CAAC;AAEF,MAAM,WAAW,GAAuB;IACvC,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,YAAY,CAAC,sBAAsB;IACzC,OAAO,EAAE,8CAA8C;CACvD,CAAC;AAEF,MAAM,cAAc,GAAuB;IAC1C,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,YAAY,CAAC,wBAAwB;IAC3C,OAAO,EAAE,kEAAkE;CAC3E,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACpC,OAAgB,EAChB,IAAyB,EACzB,EAAE,UAAU,GAAG,UAAU,KAA6B,EAAE;IAExD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;QAC/C,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,YAAY,CAAC,iBAAiB;gBACpC,OAAO,EACN,qHAAqH;aACtH,CAAC;QACH,CAAC;IACF,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,gBAAgB,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEhE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1C,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,YAAY,CAAC,SAAS;YAC5B,OAAO,EAAE,8BAA8B,UAAU,GAAG;SACpD,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IAClC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK;QAAE,OAAO,WAAW,CAAC;IAE9C,yDAAyD;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC;IAC7C,IAAI,SAAS,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;QAAE,OAAO,WAAW,CAAC;IAEpE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"api-token.js","sourceRoot":"","sources":["../../src/http/api-token.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smtp-config.d.ts","sourceRoot":"","sources":["../../src/notifications/smtp-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"smtp-config.d.ts","sourceRoot":"","sources":["../../src/notifications/smtp-config.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;CACb;AAED,kGAAkG;AAClG,MAAM,WAAW,OAAO;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAClC;AAOD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAuB9D"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readBool } from '../compute/limits.js';
|
|
1
2
|
function parsePort(raw) {
|
|
2
3
|
const n = Number(raw ?? 587);
|
|
3
4
|
return Number.isInteger(n) && n > 0 && n < 65536 ? n : 587;
|
|
@@ -32,8 +33,9 @@ export function readSmtpConfig(env) {
|
|
|
32
33
|
host,
|
|
33
34
|
port,
|
|
34
35
|
// Port 465 is implicit TLS; 587 and 25 start plaintext and upgrade via
|
|
35
|
-
// STARTTLS, which nodemailer does on its own when `secure` is false.
|
|
36
|
-
|
|
36
|
+
// STARTTLS, which nodemailer does on its own when `secure` is false. Parsed
|
|
37
|
+
// with the manifest's boolean words, so what `selva config show` reports runs.
|
|
38
|
+
secure: readBool({ SMTP_SECURE: env.SMTP_SECURE }, 'SMTP_SECURE', port === 465),
|
|
37
39
|
auth: user && pass ? { user, pass } : undefined,
|
|
38
40
|
from
|
|
39
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smtp-config.js","sourceRoot":"","sources":["../../src/notifications/smtp-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"smtp-config.js","sourceRoot":"","sources":["../../src/notifications/smtp-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAyBhD,SAAS,SAAS,CAAC,GAAuB;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC;IAE3B,OAAO;QACN,IAAI;QACJ,IAAI;QACJ,uEAAuE;QACvE,4EAA4E;QAC5E,+EAA+E;QAC/E,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,KAAK,GAAG,CAAC;QAC/E,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;QAC/C,IAAI;KACJ,CAAC;AACH,CAAC"}
|
package/dist/oauth/index.d.ts
CHANGED
|
@@ -14,12 +14,13 @@
|
|
|
14
14
|
* by whoever holds the PKCE verifier.
|
|
15
15
|
*/
|
|
16
16
|
/** The scopes a grant can carry. Each maps to one org-wide API scope. */
|
|
17
|
-
export declare const OAUTH_SCOPES: readonly ["read", "solve", "upload"];
|
|
17
|
+
export declare const OAUTH_SCOPES: readonly ["read", "solve", "upload", "create_projects"];
|
|
18
18
|
export type OAuthScope = (typeof OAUTH_SCOPES)[number];
|
|
19
19
|
/**
|
|
20
20
|
* All a registered (DCR or CIMD) client can be granted. Its name and redirects
|
|
21
21
|
* are whatever the registrant chose, so `upload`, which puts code on the org's
|
|
22
|
-
* Compute server,
|
|
22
|
+
* Compute server, and `create_projects` stay with the built-in client and a
|
|
23
|
+
* look-alike can't phish for them.
|
|
23
24
|
*/
|
|
24
25
|
export declare const REGISTERED_CLIENT_SCOPES: readonly ["read", "solve"];
|
|
25
26
|
/** The Grasshopper plugin's client id. Built in, so it needs no registration and works air-gapped. */
|
|
@@ -67,8 +68,10 @@ export interface Grant {
|
|
|
67
68
|
export interface OAuthServerOptions {
|
|
68
69
|
/** This instance's origin, e.g. `https://selva.example.com`. */
|
|
69
70
|
origin: string;
|
|
70
|
-
/** `SELVA_HMAC_KEY`.
|
|
71
|
+
/** `SELVA_HMAC_KEY`. Signs client ids and seals codes. */
|
|
71
72
|
secret: string;
|
|
73
|
+
/** The key before the last rotation: client ids and codes it made still verify. */
|
|
74
|
+
previousSecret?: string;
|
|
72
75
|
/**
|
|
73
76
|
* Fetches a Client ID Metadata Document. The URL comes from an unknown client,
|
|
74
77
|
* so the host must guard it against SSRF. Without it, URL client ids are refused.
|
|
@@ -109,7 +112,7 @@ export declare function authorizationServerMetadata(origin: string): {
|
|
|
109
112
|
grant_types_supported: string[];
|
|
110
113
|
code_challenge_methods_supported: string[];
|
|
111
114
|
token_endpoint_auth_methods_supported: string[];
|
|
112
|
-
scopes_supported: ("read" | "solve" | "upload")[];
|
|
115
|
+
scopes_supported: ("read" | "solve" | "upload" | "create_projects")[];
|
|
113
116
|
client_id_metadata_document_supported: boolean;
|
|
114
117
|
authorization_response_iss_parameter_supported: boolean;
|
|
115
118
|
};
|
|
@@ -135,7 +138,7 @@ export declare function createOAuthServer(options: OAuthServerOptions): {
|
|
|
135
138
|
grant_types_supported: string[];
|
|
136
139
|
code_challenge_methods_supported: string[];
|
|
137
140
|
token_endpoint_auth_methods_supported: string[];
|
|
138
|
-
scopes_supported: ("read" | "solve" | "upload")[];
|
|
141
|
+
scopes_supported: ("read" | "solve" | "upload" | "create_projects")[];
|
|
139
142
|
client_id_metadata_document_supported: boolean;
|
|
140
143
|
authorization_response_iss_parameter_supported: boolean;
|
|
141
144
|
};
|