@cdmbase/wiki-browser 12.0.18-alpha.49 → 12.0.18-alpha.50

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.
@@ -540,6 +540,27 @@
540
540
  "updatedAt": "Recently",
541
541
  "frontmatter": {}
542
542
  },
543
+ {
544
+ "contentId": "adminide-modules-preferences-contributes-configuration",
545
+ "slug": "preferences-contributes-configuration",
546
+ "filePath": "/content/docs/adminide-modules/preferences/contributes-configuration.md",
547
+ "relativePath": "adminide-modules/preferences/contributes-configuration.md",
548
+ "categoryId": "adminide-modules",
549
+ "title": "Contributes Configuration - defaultValueSource",
550
+ "description": "How to use defaultValueSource to resolve configuration defaults from vault secrets or environment variables",
551
+ "author": "Documentation",
552
+ "updatedAt": "2025-04-02T00:00:00",
553
+ "frontmatter": {
554
+ "meta": "",
555
+ "title": "Contributes Configuration - defaultValueSource",
556
+ "description": "How to use defaultValueSource to resolve configuration defaults from vault secrets or environment variables",
557
+ "date": "2025-04-02T00:00:00",
558
+ "updated": "2025-04-02T00:00:00",
559
+ "excerpt": "Contributes Configuration - defaultValueSource...",
560
+ "headers": "",
561
+ "Cache-Control": "no-cache"
562
+ }
563
+ },
543
564
  {
544
565
  "contentId": "adminide-modules-preferences-credentials-contribution",
545
566
  "slug": "preferences-credentials-contribution",
@@ -3877,6 +3898,15 @@
3877
3898
  "updatedAt": "Recently",
3878
3899
  "categoryId": "adminide-modules"
3879
3900
  },
3901
+ {
3902
+ "id": "adminide-modules-preferences-contributes-configuration",
3903
+ "title": "Contributes Configuration - defaultValueSource",
3904
+ "description": "How to use defaultValueSource to resolve configuration defaults from vault secrets or environment variables",
3905
+ "slug": "preferences-contributes-configuration",
3906
+ "author": "Documentation",
3907
+ "updatedAt": "2025-04-02T00:00:00",
3908
+ "categoryId": "adminide-modules"
3909
+ },
3880
3910
  {
3881
3911
  "id": "adminide-modules-preferences-credentials-contribution",
3882
3912
  "title": "Credentials Contribution",
@@ -5529,6 +5559,7 @@
5529
5559
  "adminide-modules-preferences-policy-configuration": "/content/docs/adminide-modules/preferences/Policy-Configuration.md",
5530
5560
  "adminide-modules-preferences-ui-components-resourcesettingsloader": "/content/docs/adminide-modules/preferences/UI-components/ResourceSettingsLoader.md",
5531
5561
  "adminide-modules-preferences-contribute_scope_target": "/content/docs/adminide-modules/preferences/contribute_scope_target.md",
5562
+ "adminide-modules-preferences-contributes-configuration": "/content/docs/adminide-modules/preferences/contributes-configuration.md",
5532
5563
  "adminide-modules-preferences-credentials-contribution": "/content/docs/adminide-modules/preferences/credentials-contribution.md",
5533
5564
  "adminide-modules-preferences-generate-urii": "/content/docs/adminide-modules/preferences/generate-urii.md",
5534
5565
  "adminide-modules-preferences-machine-configuration": "/content/docs/adminide-modules/preferences/machine-configuration.md",
@@ -6153,6 +6184,30 @@
6153
6184
  "updatedAt": "Recently",
6154
6185
  "frontmatter": {}
6155
6186
  },
6187
+ {
6188
+ "type": "file",
6189
+ "name": "contributes-configuration",
6190
+ "title": "Contributes Configuration - defaultValueSource",
6191
+ "path": "adminide-modules/preferences/contributes-configuration.md",
6192
+ "contentId": "adminide-modules-preferences-contributes-configuration",
6193
+ "slug": "preferences-contributes-configuration",
6194
+ "categoryId": "adminide-modules",
6195
+ "filePath": "/content/docs/adminide-modules/preferences/contributes-configuration.md",
6196
+ "relativePath": "adminide-modules/preferences/contributes-configuration.md",
6197
+ "description": "How to use defaultValueSource to resolve configuration defaults from vault secrets or environment variables",
6198
+ "author": "Documentation",
6199
+ "updatedAt": "2025-04-02T00:00:00",
6200
+ "frontmatter": {
6201
+ "meta": "",
6202
+ "title": "Contributes Configuration - defaultValueSource",
6203
+ "description": "How to use defaultValueSource to resolve configuration defaults from vault secrets or environment variables",
6204
+ "date": "2025-04-02T00:00:00",
6205
+ "updated": "2025-04-02T00:00:00",
6206
+ "excerpt": "Contributes Configuration - defaultValueSource...",
6207
+ "headers": "",
6208
+ "Cache-Control": "no-cache"
6209
+ }
6210
+ },
6156
6211
  {
6157
6212
  "type": "file",
6158
6213
  "name": "credentials-contribution",
@@ -10421,6 +10476,12 @@
10421
10476
  "children": [],
10422
10477
  "isFile": true
10423
10478
  },
10479
+ {
10480
+ "title": "Contributes Configuration - defaultValueSource",
10481
+ "path": "/help/adminide-modules/preferences-contributes-configuration",
10482
+ "children": [],
10483
+ "isFile": true
10484
+ },
10424
10485
  {
10425
10486
  "title": "Credentials Contribution",
10426
10487
  "path": "/help/adminide-modules/preferences-credentials-contribution",
@@ -0,0 +1,332 @@
1
+ ---
2
+ meta:
3
+ title: Contributes Configuration - defaultValueSource
4
+ description: How to use defaultValueSource to resolve configuration defaults from vault secrets or environment variables
5
+ date: '2025-04-02T00:00:00'
6
+ updated: '2025-04-02T00:00:00'
7
+ excerpt: Contributes Configuration - defaultValueSource...
8
+ headers:
9
+ Cache-Control: no-cache
10
+ ---
11
+
12
+ # Contributes Configuration — `defaultValueSource`
13
+
14
+ When defining contributed configuration properties, you can specify a `defaultValueSource` to tell the system **where** the default value should come from at runtime. Instead of hard-coding secrets or environment-specific URLs into configuration defaults, you declare the resolution strategy and the server resolves the actual value when settings are read.
15
+
16
+ ## Configuration Key vs Value Storage
17
+
18
+ The **configuration key** (e.g. `connector.github.clientSecret`) is defined by the **scope** — the scope determines _where_ the key is visible and at which level it can be set.
19
+
20
+ The **configuration value** storage depends on `defaultValueSource.type`:
21
+
22
+ | `defaultValueSource.type` | Value Stored In |
23
+ | ------------------------- | ---------------------------------------------------- |
24
+ | _(not set)_ | Project settings (default — stored in settings JSON) |
25
+ | `environment` | Resolved from environment variables at read time |
26
+ | `vault` | Stored in / retrieved from the vault system |
27
+
28
+ For `WINDOW` (organization) scope without a vault source, the value is stored in **organization settings**.
29
+
30
+ For `APPLICATION` scope (schemaId `uiLayout`), the value is stored in the **Application collection** under `settings`.
31
+
32
+ ## GraphQL Schema
33
+
34
+ ```graphql
35
+ enum ContributeDefaultValueSourceType {
36
+ """
37
+ Resolve from a vault secret (e.g., API keys, OAuth secrets)
38
+ """
39
+ vault
40
+ """
41
+ Resolve by substituting environment variables in the default value template
42
+ """
43
+ environment
44
+ }
45
+
46
+ type ContributeDefaultValueSource {
47
+ """
48
+ The source type for default value resolution
49
+ """
50
+ type: ContributeDefaultValueSourceType!
51
+ """
52
+ The secret type (e.g., OAUTH_CLIENT, API_KEY). Used when type=vault.
53
+ """
54
+ secretType: String
55
+ """
56
+ The vault key name (e.g., CONTENTFUL_CLIENT_SECRET). Used when type=vault.
57
+ """
58
+ secretKey: String
59
+ """
60
+ Whether the secret requires a signature for access. Used when type=vault.
61
+ """
62
+ requiredSignature: Boolean
63
+ }
64
+ ```
65
+
66
+ ## TypeScript Enum
67
+
68
+ The generated enum uses PascalCase values:
69
+
70
+ ```ts
71
+ import { ContributeDefaultValueSourceType } from '@adminide-stack/common/server';
72
+
73
+ ContributeDefaultValueSourceType.Vault; // 'vault'
74
+ ContributeDefaultValueSourceType.Environment; // 'environment'
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Type: `vault`
80
+
81
+ Use `vault` when the configuration property holds a **secret** (API key, OAuth client secret, token, etc.) that should be stored in and retrieved from the vault system.
82
+
83
+ ### How It Works
84
+
85
+ 1. The property must have `format: 'secret'` and `writeOnly: true`.
86
+ 2. When the user saves a value, it is stored in the vault (not in the settings JSON).
87
+ 3. When settings are read, the server calls `secretResolverService.resolveSecretReference()` to fetch the real value from the vault.
88
+ 4. If no vault password/token is provided in the request, the value is masked as `'xxxxx'`.
89
+
90
+ ### Vault Routing by Scope
91
+
92
+ When `defaultValueSource.type` is `vault`, the scope determines **which vault** the secret is stored in:
93
+
94
+ | Scope | Value | Vault Target |
95
+ | ------------------------- | ----- | ------------------------ |
96
+ | `APPLICATION` (1) | 1 | Personal (account) vault |
97
+ | `MACHINE` (2) | 2 | Personal (account) vault |
98
+ | `RESOURCE` (4) | 4 | Project vault |
99
+ | `MACHINE_OVERRIDABLE` (6) | 6 | Provider project vault |
100
+
101
+ ### Example — Vault Secret
102
+
103
+ ```ts
104
+ addField('apiKey', {
105
+ type: 'string',
106
+ title: 'API Key',
107
+ format: 'secret',
108
+ default: '',
109
+ writeOnly: true,
110
+ scope: ConfigurationScope.MACHINE,
111
+ defaultValueSource: {
112
+ type: 'vault',
113
+ secretType: 'API_KEY',
114
+ secretKey: 'CONTENTFUL_API_KEY',
115
+ },
116
+ });
117
+ ```
118
+
119
+ ### `defaultValueSource` Fields for Vault
120
+
121
+ | Field | Required | Description |
122
+ | ------------------- | -------- | ------------------------------------------------------------------ |
123
+ | `type` | Yes | Must be `'vault'` |
124
+ | `secretType` | Yes | Category: `'OAUTH_CLIENT'`, `'API_KEY'`, `'ENVIRONMENT_VAR'`, etc. |
125
+ | `secretKey` | Yes | Key name in the vault, e.g. `'GITHUB_CLIENT_SECRET'` |
126
+ | `requiredSignature` | No | If `true`, the secret requires a signature for access |
127
+
128
+ ### Example — OAuth Client Secret
129
+
130
+ ```ts
131
+ addField('clientSecret', {
132
+ type: 'string',
133
+ title: 'Client Secret',
134
+ format: 'secret',
135
+ default: '',
136
+ writeOnly: true,
137
+ scope: ConfigurationScope.MACHINE,
138
+ defaultValueSource: {
139
+ type: 'vault',
140
+ secretType: 'OAUTH_CLIENT',
141
+ secretKey: 'GITHUB_CLIENT_SECRET',
142
+ requiredSignature: true,
143
+ },
144
+ });
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Type: `environment`
150
+
151
+ Use `environment` when the default value should be **built from environment variables** at runtime. This is useful for URLs and endpoints that differ per deployment (local dev, staging, production) without storing them as secrets.
152
+
153
+ ### How It Works
154
+
155
+ 1. The `default` value is a **template string** using `{{VAR_NAME}}` (Mustache-style double curly braces) as placeholders.
156
+ 2. When settings are read, the server replaces each `{{VAR_NAME}}` with the corresponding validated environment variable value.
157
+ 3. Only variables listed in the **allowlist** (`allowed-env-variables.ts`) are resolved. Unlisted variables resolve to an empty string and produce a warning log.
158
+ 4. The resolution does **not** require the `secretResolverService` — it runs purely from the environment.
159
+
160
+ ### Template Syntax
161
+
162
+ Use **double curly braces** `{{VAR_NAME}}`:
163
+
164
+ ```
165
+ '{{CLIENT_URL}}/{{CONNECTOR_ENDPOINT}}'
166
+ ```
167
+
168
+ > **Why `{{...}}` instead of `${...}`?**
169
+ > Single-dollar syntax `'${VAR}'` triggers ESLint's [`no-template-curly-in-string`](https://eslint.org/docs/latest/rules/no-template-curly-in-string) rule because it looks like a JavaScript template literal. Double curly braces are a widely recognized convention (Helm, Handlebars, Angular, Jinja2) and avoid this lint error.
170
+
171
+ ### Allowed Environment Variables
172
+
173
+ Only variables registered in `allowed-env-variables.ts` can be resolved. This prevents leaking sensitive environment variables (e.g. `MONGO_URL`, database credentials) through settings.
174
+
175
+ ```ts
176
+ // packages/adminide-platform/server/src/config/allowed-env-variables.ts
177
+ import { str, cleanEnv } from 'envalid';
178
+
179
+ export const exposableEnvConfig = cleanEnv(process.env, {
180
+ CLIENT_URL: str({ default: '', devDefault: 'http://localhost:3000' }),
181
+ CONNECTOR_ENDPOINT: str({ default: '', devDefault: 'connector-callback' }),
182
+ APP_URL: str({ default: '', devDefault: 'http://localhost:3000' }),
183
+ API_URL: str({ default: '', devDefault: 'http://localhost:8080' }),
184
+ OAUTH_REDIRECT_BASE_URL: str({ default: '', devDefault: 'http://localhost:3000' }),
185
+ });
186
+
187
+ export const ALLOWED_ENV_VARIABLES: ReadonlySet<string> = new Set(Object.keys(exposableEnvConfig));
188
+ ```
189
+
190
+ Each variable uses [`envalid`](https://github.com/af/envalid) validation with:
191
+
192
+ - **`default`**: Fallback for production (empty string means the env var must be set in production).
193
+ - **`devDefault`**: Fallback for local development (`NODE_ENV !== 'production'`).
194
+
195
+ ### Adding a New Environment Variable
196
+
197
+ 1. Add the variable to `exposableEnvConfig` in `allowed-env-variables.ts`.
198
+ 2. Set the env var in your deployment (`.env`, Helm values, etc.).
199
+ 3. Reference it in your configuration property's `default` using `{{VAR_NAME}}`.
200
+
201
+ ### Example — Redirect URI from Environment
202
+
203
+ ```ts
204
+ addField('redirectUri', {
205
+ type: 'string',
206
+ title: 'Redirect URI',
207
+ default: '{{CLIENT_URL}}/{{CONNECTOR_ENDPOINT}}',
208
+ readOnly: true,
209
+ scope: ConfigurationScope.MACHINE,
210
+ defaultValueSource: {
211
+ type: 'environment',
212
+ },
213
+ });
214
+ ```
215
+
216
+ At runtime, if `CLIENT_URL=https://app.example.com` and `CONNECTOR_ENDPOINT=connector-callback`, the resolved value is:
217
+
218
+ ```
219
+ https://app.example.com/connector-callback
220
+ ```
221
+
222
+ In local development (no env vars set), `devDefault` values are used:
223
+
224
+ ```
225
+ http://localhost:3000/connector-callback
226
+ ```
227
+
228
+ ### `defaultValueSource` Fields for Environment
229
+
230
+ | Field | Required | Description |
231
+ | ------ | -------- | ----------------------- |
232
+ | `type` | Yes | Must be `'environment'` |
233
+
234
+ No other fields are needed — the variable names come from the `{{...}}` placeholders in the `default` value.
235
+
236
+ ---
237
+
238
+ ## Resolution Flow
239
+
240
+ ```
241
+ ┌──────────────────────┐
242
+ │ Read settings for key │
243
+ └──────────┬───────────┘
244
+
245
+ ┌──────────▼───────────┐
246
+ │ Has defaultValueSource│
247
+ │ on metadata? │
248
+ └──────────┬───────────┘
249
+
250
+ ┌───────────────┼───────────────┐
251
+ │ │
252
+ type = environment type = vault
253
+ │ │
254
+ ┌────────────▼───────────┐ ┌───────────▼──────────┐
255
+ │ Replace {{VAR}} with │ │ Has vault password/ │
256
+ │ allowlisted env values │ │ token in request? │
257
+ └────────────┬───────────┘ └───────────┬──────────┘
258
+ │ Yes │ No
259
+ │ ┌──────────┼──────────┐
260
+ │ │ │
261
+ │ ┌─────────▼────────┐ ┌────────▼──────┐
262
+ │ │ resolveSecret() │ │ Return xxxxx │
263
+ │ └─────────┬────────┘ └───────────────┘
264
+ │ │
265
+ ▼ ▼
266
+ Resolved value Resolved value
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Full Example — Mixed Vault and Environment in One Connector
272
+
273
+ A connector extension typically uses both types together:
274
+
275
+ ```ts
276
+ // Redirect URI — resolved from environment
277
+ addField('redirectUri', {
278
+ type: 'string',
279
+ title: 'Redirect URI',
280
+ default: '{{CLIENT_URL}}/{{CONNECTOR_ENDPOINT}}',
281
+ readOnly: true,
282
+ scope: ConfigurationScope.MACHINE,
283
+ defaultValueSource: { type: 'environment' },
284
+ });
285
+
286
+ // Client ID — resolved from vault
287
+ addField('clientId', {
288
+ type: 'string',
289
+ title: 'Client ID',
290
+ format: 'secret',
291
+ default: '',
292
+ writeOnly: true,
293
+ scope: ConfigurationScope.MACHINE,
294
+ defaultValueSource: {
295
+ type: 'vault',
296
+ secretType: 'OAUTH_CLIENT',
297
+ secretKey: 'GITHUB_CLIENT_ID',
298
+ },
299
+ });
300
+
301
+ // Client Secret — resolved from vault
302
+ addField('clientSecret', {
303
+ type: 'string',
304
+ title: 'Client Secret',
305
+ format: 'secret',
306
+ default: '',
307
+ writeOnly: true,
308
+ scope: ConfigurationScope.MACHINE,
309
+ defaultValueSource: {
310
+ type: 'vault',
311
+ secretType: 'OAUTH_CLIENT',
312
+ secretKey: 'GITHUB_CLIENT_SECRET',
313
+ },
314
+ });
315
+ ```
316
+
317
+ ---
318
+
319
+ ## Key Files
320
+
321
+ | File | Purpose |
322
+ | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
323
+ | `adminide-platform/server/src/config/allowed-env-variables.ts` | Allowlist of exposable environment variables with envalid validation |
324
+ | `adminide-platform/server/src/services/preferences/preferences-service.ts` | `_resolveDefaultValueSourceForConfigKey()` — the resolution logic |
325
+ | `adminide-platform/server/src/graphql/schema/contribution-settings-schema.graphql` | GraphQL enum and type definitions |
326
+ | `common/src/generated/generated-models.ts` | Generated TypeScript enum `ContributeDefaultValueSourceType` |
327
+
328
+ ## Security Notes
329
+
330
+ - **Vault secrets** are never returned in plaintext unless the request includes a valid vault password/token.
331
+ - **Environment variables** are restricted to an explicit allowlist. Sensitive variables like `MONGO_URL`, `JWT_SECRET`, database passwords, etc. are **never** exposed through this mechanism.
332
+ - The allowlist is validated at server startup via `envalid`. Missing required variables in production will cause a startup error.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdmbase/wiki-browser",
3
- "version": "12.0.18-alpha.49",
3
+ "version": "12.0.18-alpha.50",
4
4
  "description": "Sample core for higher packages to depend on",
5
5
  "license": "ISC",
6
6
  "author": "CDMBase LLC",
@@ -65,7 +65,7 @@
65
65
  }
66
66
  ]
67
67
  },
68
- "gitHead": "3c1a1c817bd7a4c486259bba60746627fd9068b8",
68
+ "gitHead": "ad35818a795169e2e81e6ff6a1248098befbe459",
69
69
  "typescript": {
70
70
  "definition": "lib/index.d.ts"
71
71
  }