@wtfalch/foundry 0.16.11 → 0.16.13
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.
|
@@ -108,7 +108,7 @@ export function guardStepDeps(executor, redactor, deliverSecret, heldKeys) {
|
|
|
108
108
|
// #201: ai's own default minter needs heldKeys too, to re-sign a mint
|
|
109
109
|
// request against its signing key when an earlier run pinned it but
|
|
110
110
|
// crashed before the management key itself was minted and delivered.
|
|
111
|
-
if (key === 'archon' || key === 'ai' || 'heldKeys' in copy)
|
|
111
|
+
if (key === 'archon' || key === 'ai' || key === 'auth' || 'heldKeys' in copy)
|
|
112
112
|
copy.heldKeys = heldKeys;
|
|
113
113
|
out[key] = copy;
|
|
114
114
|
}
|
|
@@ -1021,7 +1021,7 @@ function planSfu(platform) {
|
|
|
1021
1021
|
* #211 round 2: a recorded broker id is not the same as a *deployed* broker
|
|
1022
1022
|
* ({@link PLATFORM_AUTH_BROKER_DEPLOYED_SCOPE_KEY}) -- `provisionPlatformAuth`
|
|
1023
1023
|
* creates and records the app before it has `ZITADEL_SERVICE_USER_TOKEN`/
|
|
1024
|
-
* `
|
|
1024
|
+
* `LETTERMINT_API_TOKEN` to deploy it with (#209, #210). So this still plans the
|
|
1025
1025
|
* step again while the broker sits undeployed: `executorBlocked` (from
|
|
1026
1026
|
* `authBrokerBlockedReason`) reports it blocked, by name, for as long as the
|
|
1027
1027
|
* inputs stay missing, and the moment they arrive the same replanned step
|
|
@@ -28,6 +28,19 @@ export interface PlatformAuthDeps {
|
|
|
28
28
|
*/
|
|
29
29
|
zitadelForInstance?: (issuerUrl: string) => PlatformAuthDeps['zitadel'];
|
|
30
30
|
deliverSecret: FoundryStepExecutorPorts['deliverSecret'];
|
|
31
|
+
/**
|
|
32
|
+
* #210: reads back the broker's Lettermint mail key, held under
|
|
33
|
+
* {@link PLATFORM_AUTH_BROKER_MAIL_KEY_REF}. Never minted here -- unlike
|
|
34
|
+
* the login-client token above, foundry has no Lettermint account of its
|
|
35
|
+
* own to mint one from, so this only ever reads back a value a human (or
|
|
36
|
+
* Archon's own onboarding) put there directly once Lettermint issued it.
|
|
37
|
+
* Absent, or with nothing held under that ref yet, `LETTERMINT_API_TOKEN`
|
|
38
|
+
* stays a gap `missingBrokerInputs` reports by name, the same "blocked,
|
|
39
|
+
* not failing" every other unmet broker input already follows.
|
|
40
|
+
*/
|
|
41
|
+
heldKeys?: {
|
|
42
|
+
resolve(ref: string): Promise<string | null>;
|
|
43
|
+
};
|
|
31
44
|
/** Clock, sleep and fetch for the readiness wait and delivery retries; real ones by default. */
|
|
32
45
|
runtime?: PlatformAuthRuntime;
|
|
33
46
|
}
|
|
@@ -234,6 +247,15 @@ export declare class FoundryPlatformStepExecutor implements PlatformStepExecutor
|
|
|
234
247
|
* key delivered under `zitadel:platform:admin`.
|
|
235
248
|
*/
|
|
236
249
|
export declare const PLATFORM_AUTH_INSTANCE_BEARER_REF = "zitadel:platform:instanceBearer";
|
|
250
|
+
/**
|
|
251
|
+
* #210: the ref the broker's Lettermint mail key is held under. Unlike every
|
|
252
|
+
* other `_REF` in this file, nothing here ever delivers a value under it --
|
|
253
|
+
* {@link PlatformAuthDeps.heldKeys} only reads it back, once a human (or
|
|
254
|
+
* Archon's own onboarding) puts it there directly with the key Lettermint
|
|
255
|
+
* issued, on one allowed to send from every app's domain
|
|
256
|
+
* (`wtfalch/auth/docs/deploy.md`).
|
|
257
|
+
*/
|
|
258
|
+
export declare const PLATFORM_AUTH_BROKER_MAIL_KEY_REF = "lettermint:platform:apiToken";
|
|
237
259
|
/**
|
|
238
260
|
* The fixed description Stalwart's admin API key is minted under
|
|
239
261
|
* (`StalwartClient.createApiKey`'s own signature returns only the secret,
|
|
@@ -591,13 +613,14 @@ export declare function createAiManagementKeyMinter(options: {
|
|
|
591
613
|
}): AiManagementKeyMinter;
|
|
592
614
|
/**
|
|
593
615
|
* #211: names of the envs the platform's sign-in broker (`wtfalch/auth`'s
|
|
594
|
-
* `broker/server.ts`) refuses to start without
|
|
595
|
-
*
|
|
596
|
-
* (#
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
616
|
+
* `broker/server.ts`) refuses to start without -- `ZITADEL_SERVICE_USER_TOKEN`/
|
|
617
|
+
* `_FILE` (#209 mints and pushes this once it lands) and `LETTERMINT_API_TOKEN`
|
|
618
|
+
* (#210: `wtfalch/auth#138` moved the broker's account mail onto
|
|
619
|
+
* `@wtfalch/mailer`'s Lettermint transport, so this is the env name the
|
|
620
|
+
* broker actually reads now, not `RESEND_API_TOKEN`). Read from the broker's
|
|
621
|
+
* own live env, not a recorded scope id: whichever of #209/#210 lands first
|
|
622
|
+
* (or a human, setting either directly on the app) is enough to clear that
|
|
623
|
+
* one input, in either order, with no coupling to this step's own execution.
|
|
601
624
|
*
|
|
602
625
|
* #211 round 3: `AUTH_APPS` is a third required input -- the broker's own
|
|
603
626
|
* `parseApps` refuses to start with no `AUTH_APPS` set or an empty array
|
|
@@ -577,6 +577,15 @@ const PLATFORM_AUTH_ORG_NAME = 'foundry';
|
|
|
577
577
|
*/
|
|
578
578
|
export const PLATFORM_AUTH_INSTANCE_BEARER_REF = 'zitadel:platform:instanceBearer';
|
|
579
579
|
const PLATFORM_AUTH_BEARER_USER_NAME = 'foundry-instance-owner';
|
|
580
|
+
/**
|
|
581
|
+
* #210: the ref the broker's Lettermint mail key is held under. Unlike every
|
|
582
|
+
* other `_REF` in this file, nothing here ever delivers a value under it --
|
|
583
|
+
* {@link PlatformAuthDeps.heldKeys} only reads it back, once a human (or
|
|
584
|
+
* Archon's own onboarding) puts it there directly with the key Lettermint
|
|
585
|
+
* issued, on one allowed to send from every app's domain
|
|
586
|
+
* (`wtfalch/auth/docs/deploy.md`).
|
|
587
|
+
*/
|
|
588
|
+
export const PLATFORM_AUTH_BROKER_MAIL_KEY_REF = 'lettermint:platform:apiToken';
|
|
580
589
|
/**
|
|
581
590
|
* Retries `action` up to `attempts` times, sleeping increasingly between
|
|
582
591
|
* tries -- the same shape the admin machine user's own delivery retry (just
|
|
@@ -811,10 +820,15 @@ async function liveLoginClientTokenHash(coolify, appId) {
|
|
|
811
820
|
* `IAM_LOGIN_CLIENT` machine user (never the admin one, which is
|
|
812
821
|
* `IAM_OWNER`) and delivers its token to both apps, once the broker's
|
|
813
822
|
* other required inputs are already met.
|
|
814
|
-
* - The broker never receives `RESEND_API_TOKEN` either, so it will not
|
|
815
|
-
* on `AUTH_APPS` alone
|
|
816
|
-
*
|
|
817
|
-
*
|
|
823
|
+
* - ~~The broker never receives `RESEND_API_TOKEN` either, so it will not
|
|
824
|
+
* start on `AUTH_APPS` alone.~~ Closed by #210, once `wtfalch/auth#138`
|
|
825
|
+
* moved the broker's account mail onto `@wtfalch/mailer`'s Lettermint
|
|
826
|
+
* transport: this function now reads the key back from
|
|
827
|
+
* {@link PlatformAuthDeps.heldKeys} under
|
|
828
|
+
* {@link PLATFORM_AUTH_BROKER_MAIL_KEY_REF} and pushes it as
|
|
829
|
+
* `LETTERMINT_API_TOKEN`, once a human (or Archon's own onboarding) has
|
|
830
|
+
* put one there. Still a gap until then, the same "blocked, not failing"
|
|
831
|
+
* way an unset `AUTH_APPS` already is.
|
|
818
832
|
* - `AUTH_APPS` starts unset: the broker has nothing to serve until a
|
|
819
833
|
* platform app registers with it ({@link provisionPlatformArchon} is the
|
|
820
834
|
* first), so it will not start (`parseApps` throws on an empty list) until
|
|
@@ -1043,14 +1057,24 @@ async function provisionPlatformAuth(context, deps) {
|
|
|
1043
1057
|
{ key: 'OTEL_NODE_RESOURCE_DETECTORS', value: 'none' },
|
|
1044
1058
|
{ key: 'API_CACHE_CONFIG', value: '{"defaultMinutes":2,"longMinutes":5}' },
|
|
1045
1059
|
];
|
|
1046
|
-
//
|
|
1047
|
-
//
|
|
1060
|
+
// #210: read back now, not inside the deploy-decision block below -- this
|
|
1061
|
+
// push has to land before `missingBrokerInputs` is read a few lines down,
|
|
1062
|
+
// the same way `envsDiffer`/`bulkUpsertEnvs` below already do for every
|
|
1063
|
+
// other broker env, so a single apply that finds the key already held can
|
|
1064
|
+
// also see `LETTERMINT_API_TOKEN` as met and deploy in that same run.
|
|
1065
|
+
const heldMailKey = await deps.heldKeys?.resolve(PLATFORM_AUTH_BROKER_MAIL_KEY_REF);
|
|
1066
|
+
// `AUTH_APPS` and `ZITADEL_SERVICE_USER_TOKEN`/`_FILE` are not pushed here
|
|
1067
|
+
// -- this function's own doc comment, "Known gaps". `LETTERMINT_API_TOKEN`
|
|
1068
|
+
// is, once held (#210): pushing it costs nothing even while the broker
|
|
1069
|
+
// still cannot start on the other two, and the deploy decision below stays
|
|
1070
|
+
// gated on `missingBrokerInputs` regardless.
|
|
1048
1071
|
const brokerEnvs = [
|
|
1049
1072
|
{
|
|
1050
1073
|
key: 'ZITADEL_API_URL',
|
|
1051
1074
|
value: `http://${PLATFORM_AUTH_ZITADEL_INTERNAL_NAME}:${AUTH_ZITADEL_PORT}`,
|
|
1052
1075
|
},
|
|
1053
1076
|
{ key: 'ZITADEL_DOMAIN', value: hostname },
|
|
1077
|
+
...(heldMailKey ? [{ key: 'LETTERMINT_API_TOKEN', value: heldMailKey }] : []),
|
|
1054
1078
|
];
|
|
1055
1079
|
// Compared before the write: an env change only reaches a running
|
|
1056
1080
|
// container on its next deploy (`diff.ts`'s `coolifyCalls` follows the
|
|
@@ -1074,11 +1098,11 @@ async function provisionPlatformAuth(context, deps) {
|
|
|
1074
1098
|
await deps.coolify.deploy(loginAppId);
|
|
1075
1099
|
}
|
|
1076
1100
|
// #211: the broker's own `server.ts` refuses to start without
|
|
1077
|
-
// `ZITADEL_SERVICE_USER_TOKEN`/`_FILE` and `
|
|
1078
|
-
// it without them only produces a container that crash-loops
|
|
1079
|
-
// `/api`. The app is still created and recorded above either way,
|
|
1080
|
-
// and #210 (or a human, directly) have something to push the env
|
|
1081
|
-
// only the deploy waits.
|
|
1101
|
+
// `ZITADEL_SERVICE_USER_TOKEN`/`_FILE` and `LETTERMINT_API_TOKEN` --
|
|
1102
|
+
// deploying it without them only produces a container that crash-loops
|
|
1103
|
+
// behind `/api`. The app is still created and recorded above either way,
|
|
1104
|
+
// so #209 and #210 (or a human, directly) have something to push the env
|
|
1105
|
+
// onto; only the deploy waits.
|
|
1082
1106
|
// #211 round 5: `brokerDeployNeeded` is its own reason to deploy (not only
|
|
1083
1107
|
// alongside justCreated/running/envsChanged, none of which this function's
|
|
1084
1108
|
// own `brokerEnvs` write above ever touches `AUTH_APPS`): it is what
|
|
@@ -1262,7 +1286,7 @@ async function provisionPlatformAuth(context, deps) {
|
|
|
1262
1286
|
// envs, then redeploys both.
|
|
1263
1287
|
//
|
|
1264
1288
|
// Deferred, not blocked, while the broker's other required inputs
|
|
1265
|
-
// (`
|
|
1289
|
+
// (`LETTERMINT_API_TOKEN`, `AUTH_APPS`) are still missing (composing with
|
|
1266
1290
|
// #211's own gating): minting and delivering here would only redeploy a
|
|
1267
1291
|
// broker that still refuses to start on the other missing input, spending
|
|
1268
1292
|
// a mint and two deploys on nothing this apply can fix. `blockedSteps`'s
|
|
@@ -1967,12 +1991,12 @@ async function mailBlockedReason(platform, mail, recordedIds) {
|
|
|
1967
1991
|
}
|
|
1968
1992
|
/**
|
|
1969
1993
|
* #211: the broker cannot start without `ZITADEL_SERVICE_USER_TOKEN`/`_FILE`,
|
|
1970
|
-
* `
|
|
1971
|
-
* deploying the broker while any is missing
|
|
1972
|
-
* this is the same check surfaced through
|
|
1973
|
-
* why, by name, rather than the broker simply
|
|
1974
|
-
* explanation. `null` while there is no broker
|
|
1975
|
-
* to check) or every input is present.
|
|
1994
|
+
* `LETTERMINT_API_TOKEN` and `AUTH_APPS`. `provisionPlatformAuth` already
|
|
1995
|
+
* skips deploying the broker while any is missing
|
|
1996
|
+
* ({@link missingBrokerInputs}); this is the same check surfaced through
|
|
1997
|
+
* `blockedSteps`, so a plan says why, by name, rather than the broker simply
|
|
1998
|
+
* sitting undeployed with no explanation. `null` while there is no broker
|
|
1999
|
+
* app id recorded yet (nothing to check) or every input is present.
|
|
1976
2000
|
*
|
|
1977
2001
|
* #211 round 3: wraps the live read the way {@link mailBlockedReason} wraps
|
|
1978
2002
|
* its own Coolify call -- a transient `listEnvs` failure must report a
|
|
@@ -1986,6 +2010,21 @@ async function mailBlockedReason(platform, mail, recordedIds) {
|
|
|
1986
2010
|
* go fix an entry, not merely wait for one of #209/#210/Archon's own
|
|
1987
2011
|
* registration to supply one), and reporting it identically hid which one
|
|
1988
2012
|
* was true.
|
|
2013
|
+
*
|
|
2014
|
+
* #210: `LETTERMINT_API_TOKEN` joins `ZITADEL_SERVICE_USER_TOKEN` in being
|
|
2015
|
+
* excluded from `otherInputsMissing` -- but only while `auth.heldKeys`
|
|
2016
|
+
* actually resolves {@link PLATFORM_AUTH_BROKER_MAIL_KEY_REF} right now.
|
|
2017
|
+
* `planAuth`'s own "loop fix" stops planning this step the moment every
|
|
2018
|
+
* `otherInputsMissing` entry looks like something only another run can
|
|
2019
|
+
* supply; excluding `LETTERMINT_API_TOKEN` unconditionally (the way
|
|
2020
|
+
* `ZITADEL_SERVICE_USER_TOKEN` is, since foundry can always eventually mint
|
|
2021
|
+
* that one) would keep the step planned, and `provisionPlatformAuth`
|
|
2022
|
+
* running its full body, forever on a host that never wires `heldKeys` or
|
|
2023
|
+
* whose operator has not put a Lettermint key there yet -- exactly the
|
|
2024
|
+
* wasteful-replan bug #211 round 5 fixed for the broker deploy itself. Once
|
|
2025
|
+
* the key *is* held, excluding it lets this run's `provisionPlatformAuth`
|
|
2026
|
+
* push it (see that function's own `heldMailKey` read) and clears the gap
|
|
2027
|
+
* for good.
|
|
1989
2028
|
*/
|
|
1990
2029
|
async function authBrokerBlockedReason(auth, recordedIds) {
|
|
1991
2030
|
const brokerAppId = recordedIds[PLATFORM_AUTH_BROKER_SCOPE_KEY];
|
|
@@ -1993,9 +2032,11 @@ async function authBrokerBlockedReason(auth, recordedIds) {
|
|
|
1993
2032
|
return { reason: null, otherInputsMissing: [] };
|
|
1994
2033
|
let missing;
|
|
1995
2034
|
let authAppsRaw;
|
|
2035
|
+
let heldMailKey;
|
|
1996
2036
|
try {
|
|
1997
2037
|
missing = await missingBrokerInputs(auth.coolify, brokerAppId);
|
|
1998
2038
|
authAppsRaw = await currentEnvValue(auth.coolify, brokerAppId, 'AUTH_APPS');
|
|
2039
|
+
heldMailKey = (await auth.heldKeys?.resolve(PLATFORM_AUTH_BROKER_MAIL_KEY_REF)) ?? null;
|
|
1999
2040
|
}
|
|
2000
2041
|
catch {
|
|
2001
2042
|
return {
|
|
@@ -2007,13 +2048,19 @@ async function authBrokerBlockedReason(auth, recordedIds) {
|
|
|
2007
2048
|
}
|
|
2008
2049
|
// #216 round 5: what `provisionPlatformAuth`'s own `loginClientOtherInputsMissing`
|
|
2009
2050
|
// gate is -- see `planAuth`'s own doc comment for why it needs this too.
|
|
2010
|
-
|
|
2051
|
+
// #210: and `LETTERMINT_API_TOKEN`, once held -- see this function's own
|
|
2052
|
+
// doc comment.
|
|
2053
|
+
const otherInputsMissing = missing.filter((m) => m !== 'ZITADEL_SERVICE_USER_TOKEN' && !(m === 'LETTERMINT_API_TOKEN' && heldMailKey));
|
|
2011
2054
|
if (missing.length === 0)
|
|
2012
2055
|
return { reason: null, otherInputsMissing };
|
|
2056
|
+
// #210: say where the operator seals the Lettermint key, not only its env name.
|
|
2057
|
+
const named = (names) => names.map((m) => m === 'LETTERMINT_API_TOKEN'
|
|
2058
|
+
? `LETTERMINT_API_TOKEN (seal it under the held-key ref ${PLATFORM_AUTH_BROKER_MAIL_KEY_REF})`
|
|
2059
|
+
: m);
|
|
2013
2060
|
if (authAppsProblem(authAppsRaw, brokerAppId) === 'malformed') {
|
|
2014
2061
|
const otherMissing = missing.filter((m) => m !== 'AUTH_APPS');
|
|
2015
2062
|
const otherSuffix = otherMissing.length > 0
|
|
2016
|
-
? `, and it has no ${otherMissing.join(' and no ')} yet (#209, #210)`
|
|
2063
|
+
? `, and it has no ${named(otherMissing).join(' and no ')} yet (#209, #210)`
|
|
2017
2064
|
: '';
|
|
2018
2065
|
return {
|
|
2019
2066
|
reason: `the platform's sign-in broker ${brokerAppId} is blocked, not deployed: its AUTH_APPS is malformed${otherSuffix}`,
|
|
@@ -2024,7 +2071,7 @@ async function authBrokerBlockedReason(auth, recordedIds) {
|
|
|
2024
2071
|
// those issues when one of them is actually among what's missing.
|
|
2025
2072
|
const suffix = missing.some((m) => m !== 'AUTH_APPS') ? ' (#209, #210)' : '';
|
|
2026
2073
|
return {
|
|
2027
|
-
reason: `the platform's sign-in broker is created but not deployed, blocked: it has no ${missing.join(' and no ')} yet${suffix}`,
|
|
2074
|
+
reason: `the platform's sign-in broker is created but not deployed, blocked: it has no ${named(missing).join(' and no ')} yet${suffix}`,
|
|
2028
2075
|
otherInputsMissing,
|
|
2029
2076
|
};
|
|
2030
2077
|
}
|
|
@@ -2197,8 +2244,8 @@ export const PLATFORM_ARCHON_CLIENT_ID_SCOPE_KEY = 'zitadel_platform_archon_clie
|
|
|
2197
2244
|
* `provisionPlatformAuth` guarantees by the time this step is reachable (its
|
|
2198
2245
|
* own resourceId records only once the broker app exists too). The broker
|
|
2199
2246
|
* will not actually be able to serve a request with this key until
|
|
2200
|
-
* `provisionPlatformAuth`'s own
|
|
2201
|
-
* `
|
|
2247
|
+
* `provisionPlatformAuth`'s own `ZITADEL_SERVICE_USER_TOKEN` is minted and
|
|
2248
|
+
* `LETTERMINT_API_TOKEN` is held; wiring the key here is still correct and
|
|
2202
2249
|
* needed so the two apps agree the moment the broker can run.
|
|
2203
2250
|
*
|
|
2204
2251
|
* Known gaps, left for review:
|
|
@@ -2421,7 +2468,10 @@ async function provisionPlatformArchon(context, deps) {
|
|
|
2421
2468
|
throw new Error(`platform:archon: app ${appId} lost its AUTH_APP_KEY between two reads`);
|
|
2422
2469
|
}
|
|
2423
2470
|
envs.push({ key: 'AUTH_APP_KEY', value: appKey });
|
|
2424
|
-
|
|
2471
|
+
// A value with a line break (the PEM management keys) must be flagged:
|
|
2472
|
+
// unflagged, Coolify writes it into `.env` unquoted and the container never
|
|
2473
|
+
// starts.
|
|
2474
|
+
envs.push(...inputs.envs.map((e) => (e.value.includes('\n') ? { ...e, multiline: true } : e)));
|
|
2425
2475
|
const changed = await envsDiffer(deps.coolify, appId, envs);
|
|
2426
2476
|
await deps.coolify.bulkUpsertEnvs(appId, envs);
|
|
2427
2477
|
// ---- register with the broker (#204) ---------------------------------------
|
|
@@ -2483,8 +2533,8 @@ async function provisionPlatformArchon(context, deps) {
|
|
|
2483
2533
|
await deps.coolify.bulkUpsertEnvs(brokerAppId, desiredAuthApps);
|
|
2484
2534
|
}
|
|
2485
2535
|
// #211 round 2: deploying the broker before its own `server.ts` can start
|
|
2486
|
-
// (missing `ZITADEL_SERVICE_USER_TOKEN`/`_FILE` or `
|
|
2487
|
-
// #210) only produces a container that crash-loops behind `/api` -- the
|
|
2536
|
+
// (missing `ZITADEL_SERVICE_USER_TOKEN`/`_FILE` or `LETTERMINT_API_TOKEN`,
|
|
2537
|
+
// #209, #210) only produces a container that crash-loops behind `/api` -- the
|
|
2488
2538
|
// same rule `provisionPlatformAuth` follows for its own deploy of this
|
|
2489
2539
|
// app. The env is still written either way, so the broker serves the new
|
|
2490
2540
|
// registration the moment it is next deployed, by either step.
|
|
@@ -3044,9 +3094,6 @@ async function collectArchonServiceInputs(platform, deps, recorded) {
|
|
|
3044
3094
|
envs.push({ key: 'INTEGRATIONS_URL', value: url }, {
|
|
3045
3095
|
key: 'INTEGRATIONS_MANAGEMENT_PRIVATE_KEY',
|
|
3046
3096
|
value: held(INTEGRATIONS_MANAGEMENT_KEY_REF),
|
|
3047
|
-
// A PEM spans lines; unflagged, Coolify writes it into `.env`
|
|
3048
|
-
// unquoted and the container never starts.
|
|
3049
|
-
multiline: true,
|
|
3050
3097
|
}, {
|
|
3051
3098
|
key: 'INTEGRATIONS_MANAGEMENT_ISSUER',
|
|
3052
3099
|
value: INTEGRATIONS_MANAGEMENT_ISSUER,
|
|
@@ -3987,13 +4034,14 @@ async function findOrCreatePlatformApp(coolify, name, environment, create) {
|
|
|
3987
4034
|
}
|
|
3988
4035
|
/**
|
|
3989
4036
|
* #211: names of the envs the platform's sign-in broker (`wtfalch/auth`'s
|
|
3990
|
-
* `broker/server.ts`) refuses to start without
|
|
3991
|
-
*
|
|
3992
|
-
* (#
|
|
3993
|
-
*
|
|
3994
|
-
*
|
|
3995
|
-
*
|
|
3996
|
-
*
|
|
4037
|
+
* `broker/server.ts`) refuses to start without -- `ZITADEL_SERVICE_USER_TOKEN`/
|
|
4038
|
+
* `_FILE` (#209 mints and pushes this once it lands) and `LETTERMINT_API_TOKEN`
|
|
4039
|
+
* (#210: `wtfalch/auth#138` moved the broker's account mail onto
|
|
4040
|
+
* `@wtfalch/mailer`'s Lettermint transport, so this is the env name the
|
|
4041
|
+
* broker actually reads now, not `RESEND_API_TOKEN`). Read from the broker's
|
|
4042
|
+
* own live env, not a recorded scope id: whichever of #209/#210 lands first
|
|
4043
|
+
* (or a human, setting either directly on the app) is enough to clear that
|
|
4044
|
+
* one input, in either order, with no coupling to this step's own execution.
|
|
3997
4045
|
*
|
|
3998
4046
|
* #211 round 3: `AUTH_APPS` is a third required input -- the broker's own
|
|
3999
4047
|
* `parseApps` refuses to start with no `AUTH_APPS` set or an empty array
|
|
@@ -4011,8 +4059,8 @@ export async function missingBrokerInputs(coolify, brokerAppId) {
|
|
|
4011
4059
|
if (!has('ZITADEL_SERVICE_USER_TOKEN') && !has('ZITADEL_SERVICE_USER_TOKEN_FILE')) {
|
|
4012
4060
|
missing.push('ZITADEL_SERVICE_USER_TOKEN');
|
|
4013
4061
|
}
|
|
4014
|
-
if (!has('
|
|
4015
|
-
missing.push('
|
|
4062
|
+
if (!has('LETTERMINT_API_TOKEN'))
|
|
4063
|
+
missing.push('LETTERMINT_API_TOKEN');
|
|
4016
4064
|
if (authAppsProblem(value('AUTH_APPS'), brokerAppId) !== null)
|
|
4017
4065
|
missing.push('AUTH_APPS');
|
|
4018
4066
|
return missing;
|