neon 3.0.0 → 3.1.0
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/README.md +54 -0
- package/dist/_shared/auth_selection.js +76 -79
- package/dist/_shared/credentials.js +166 -187
- package/dist/_shared/env-core/env.js +354 -517
- package/dist/_shared/env-core/reuse-secrets.js +159 -203
- package/dist/_shared/paths.js +129 -126
- package/dist/_shared/profiles.js +192 -242
- package/dist/_shared/secure_file.js +36 -38
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/analytics.js +163 -207
- package/dist/api.js +815 -758
- package/dist/auth.js +121 -141
- package/dist/auth_context.js +39 -53
- package/dist/cli.js +4 -7
- package/dist/commands/api.js +220 -250
- package/dist/commands/api_keys.js +251 -314
- package/dist/commands/auth.js +283 -328
- package/dist/commands/bootstrap.js +372 -437
- package/dist/commands/branches.js +304 -455
- package/dist/commands/bucket.js +374 -514
- package/dist/commands/checkout.js +213 -298
- package/dist/commands/config.js +573 -690
- package/dist/commands/connection_string.js +137 -165
- package/dist/commands/data_api.js +238 -260
- package/dist/commands/databases.js +67 -76
- package/dist/commands/deploy.js +31 -25
- package/dist/commands/dev.js +639 -719
- package/dist/commands/diff.js +156 -200
- package/dist/commands/env.js +243 -303
- package/dist/commands/functions.js +275 -355
- package/dist/commands/index.js +70 -65
- package/dist/commands/init.js +84 -119
- package/dist/commands/inspect.js +55 -55
- package/dist/commands/ip_allow.js +88 -120
- package/dist/commands/link.js +874 -1019
- package/dist/commands/logs.js +291 -0
- package/dist/commands/neon_auth.js +725 -933
- package/dist/commands/operations.js +34 -25
- package/dist/commands/orgs.js +28 -18
- package/dist/commands/profile.js +614 -845
- package/dist/commands/projects.js +313 -373
- package/dist/commands/psql.js +60 -58
- package/dist/commands/roles.js +55 -58
- package/dist/commands/schema_diff.js +87 -131
- package/dist/commands/set_context.js +34 -26
- package/dist/commands/snapshots.js +288 -413
- package/dist/commands/status.js +41 -37
- package/dist/commands/user.js +21 -10
- package/dist/commands/vpc_endpoints.js +85 -113
- package/dist/config.js +7 -6
- package/dist/config_format.js +50 -66
- package/dist/config_template.js +128 -157
- package/dist/context.js +183 -235
- package/dist/current_branch_fast_path.js +40 -49
- package/dist/dev/env.js +313 -394
- package/dist/dev/functions.js +54 -68
- package/dist/dev/inputs.js +46 -58
- package/dist/dev/runtime.js +135 -164
- package/dist/dev/websocket.js +766 -959
- package/dist/env.js +27 -33
- package/dist/env_file.js +118 -132
- package/dist/env_services.js +36 -38
- package/dist/errors.js +57 -68
- package/dist/functions_api.js +45 -43
- package/dist/help.js +189 -140
- package/dist/index.js +182 -257
- package/dist/init/agents.js +137 -118
- package/dist/init/auth.js +58 -68
- package/dist/init/bootstrap.js +325 -396
- package/dist/init/build_config.js +4 -2
- package/dist/init/detect_agent.js +56 -101
- package/dist/init/editors.js +35 -52
- package/dist/init/enrich_output.js +51 -66
- package/dist/init/extension.js +134 -171
- package/dist/init/inspect.js +179 -266
- package/dist/init/interactive.js +510 -622
- package/dist/init/neonctl.js +117 -168
- package/dist/init/orchestrate.js +157 -173
- package/dist/init/phases/auth.js +188 -202
- package/dist/init/phases/cleanup.js +23 -23
- package/dist/init/phases/db.js +251 -277
- package/dist/init/phases/getting_started.js +213 -223
- package/dist/init/phases/mcp.js +174 -224
- package/dist/init/phases/migrations.js +247 -248
- package/dist/init/phases/neon_auth.js +114 -133
- package/dist/init/phases/setup.js +546 -703
- package/dist/init/phases/skills.js +75 -86
- package/dist/init/phases/status.js +72 -67
- package/dist/init/resolve_context.js +102 -99
- package/dist/init/route_command.js +91 -98
- package/dist/init/skills.js +174 -218
- package/dist/init/vsix.js +77 -99
- package/dist/log.js +17 -16
- package/dist/neon_services.js +104 -129
- package/dist/parameters.gen.js +481 -471
- package/dist/pkg.js +17 -19
- package/dist/profile_keys.js +44 -47
- package/dist/psql/cli.js +44 -47
- package/dist/psql/command/cmd_cond.js +231 -406
- package/dist/psql/command/cmd_connect.js +557 -764
- package/dist/psql/command/cmd_copy.js +727 -983
- package/dist/psql/command/cmd_describe.js +1499 -1688
- package/dist/psql/command/cmd_format.js +733 -905
- package/dist/psql/command/cmd_io.js +1293 -2082
- package/dist/psql/command/cmd_lo.js +297 -359
- package/dist/psql/command/cmd_meta.js +727 -878
- package/dist/psql/command/cmd_misc.js +138 -172
- package/dist/psql/command/cmd_pipeline.js +547 -1099
- package/dist/psql/command/cmd_restrict.js +119 -155
- package/dist/psql/command/cmd_show.js +529 -688
- package/dist/psql/command/dispatch.js +261 -325
- package/dist/psql/command/inputQueue.js +35 -33
- package/dist/psql/command/shared.js +49 -63
- package/dist/psql/complete/filenames.js +90 -133
- package/dist/psql/complete/index.js +59 -97
- package/dist/psql/complete/matcher.js +236 -300
- package/dist/psql/complete/psqlVars.js +218 -223
- package/dist/psql/complete/queries.js +159 -177
- package/dist/psql/complete/rules.js +1493 -2299
- package/dist/psql/core/common.js +762 -1180
- package/dist/psql/core/help.js +456 -546
- package/dist/psql/core/mainloop.js +692 -1302
- package/dist/psql/core/prompt.js +391 -408
- package/dist/psql/core/settings.js +429 -644
- package/dist/psql/core/sqlHelp.js +480 -554
- package/dist/psql/core/startup.js +626 -815
- package/dist/psql/core/syncVars.js +67 -110
- package/dist/psql/core/variables.js +156 -278
- package/dist/psql/describe/formatters.js +884 -1285
- package/dist/psql/describe/processNamePattern.js +173 -260
- package/dist/psql/describe/queries.js +1368 -2403
- package/dist/psql/describe/versionGate.js +32 -41
- package/dist/psql/index.js +1414 -1927
- package/dist/psql/io/history.js +232 -271
- package/dist/psql/io/input.js +103 -108
- package/dist/psql/io/lineEditor/buffer.js +238 -319
- package/dist/psql/io/lineEditor/complete.js +135 -213
- package/dist/psql/io/lineEditor/filename.js +139 -148
- package/dist/psql/io/lineEditor/index.js +653 -870
- package/dist/psql/io/lineEditor/keymap.js +544 -702
- package/dist/psql/io/lineEditor/vt100.js +294 -341
- package/dist/psql/io/pgpass.js +158 -187
- package/dist/psql/io/pgservice.js +146 -183
- package/dist/psql/io/psqlrc.js +328 -403
- package/dist/psql/print/aligned.js +1020 -1683
- package/dist/psql/print/asciidoc.js +180 -214
- package/dist/psql/print/crosstab.js +281 -442
- package/dist/psql/print/csv.js +48 -70
- package/dist/psql/print/html.js +195 -226
- package/dist/psql/print/json.js +75 -88
- package/dist/psql/print/latex.js +291 -364
- package/dist/psql/print/pager.js +171 -242
- package/dist/psql/print/troff.js +194 -226
- package/dist/psql/print/unaligned.js +69 -95
- package/dist/psql/print/units.js +167 -169
- package/dist/psql/scanner/slash.js +428 -483
- package/dist/psql/scanner/sql.js +445 -889
- package/dist/psql/scanner/stringutils.js +309 -379
- package/dist/psql/types/index.js +2 -7
- package/dist/psql/types/scanner.js +25 -22
- package/dist/psql/wire/connection.js +2042 -2803
- package/dist/psql/wire/copy.js +84 -100
- package/dist/psql/wire/notify.js +39 -59
- package/dist/psql/wire/pipeline.js +305 -518
- package/dist/psql/wire/protocol.js +349 -417
- package/dist/psql/wire/sasl.js +180 -265
- package/dist/psql/wire/tls.js +400 -561
- package/dist/storage_api.js +115 -129
- package/dist/test_utils/fixtures.js +94 -113
- package/dist/test_utils/oauth_server.js +10 -7
- package/dist/test_utils/project_dir.js +33 -0
- package/dist/utils/ai_gateway_notice.js +131 -162
- package/dist/utils/api_enums.js +21 -28
- package/dist/utils/auth.js +10 -4
- package/dist/utils/branch_notice.js +20 -19
- package/dist/utils/branch_picker.js +83 -89
- package/dist/utils/cli_name.js +15 -12
- package/dist/utils/compute_units.js +20 -27
- package/dist/utils/config_diff.js +127 -158
- package/dist/utils/enrichers.js +95 -148
- package/dist/utils/esbuild.js +130 -189
- package/dist/utils/flags.js +35 -47
- package/dist/utils/formats.js +8 -15
- package/dist/utils/git_diff.js +69 -80
- package/dist/utils/inspect_db.js +101 -143
- package/dist/utils/inspect_queries.js +179 -142
- package/dist/utils/middlewares.js +37 -44
- package/dist/utils/openapi.js +87 -99
- package/dist/utils/package_manager.js +312 -110
- package/dist/utils/point_in_time.js +49 -53
- package/dist/utils/psql.js +89 -106
- package/dist/utils/service_picker.js +55 -58
- package/dist/utils/string.js +5 -5
- package/dist/utils/ui.js +38 -55
- package/dist/utils/write_sync.js +26 -35
- package/dist/utils/zip.js +4 -3
- package/dist/writer.js +67 -87
- package/package.json +7 -5
|
@@ -1,223 +1,179 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { NEON_ENV_VAR_KEYS, createApiFromOptions, credentialEnvKeys, credentialName, fetchEnvKeys, policyEnvKeys, previewCredentialScopes, resolveBranchPolicy, toEntries } from "./env.js";
|
|
2
|
+
import { credentialScopesSatisfied } from "@neon/config/v1";
|
|
3
|
+
//#region src/_shared/env-core/reuse-secrets.ts
|
|
3
4
|
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
// this call replaces, so revoking them strands nothing — and it keeps a branch from
|
|
106
|
-
// accumulating a live credential per call. Everything else on the branch is left alone: it
|
|
107
|
-
// may belong to a teammate, another checkout, or a deployed function, and nothing
|
|
108
|
-
// observable distinguishes those from an orphan of our own.
|
|
109
|
-
//
|
|
110
|
-
// Revoked *after* the fetch, so a failed fetch leaves the caller's existing secrets working.
|
|
111
|
-
const ours = new Set();
|
|
112
|
-
for (const meta of [named.storage, named.gateway]) {
|
|
113
|
-
if (meta !== null &&
|
|
114
|
-
meta.principalType === "user" &&
|
|
115
|
-
meta.name === credentialName(branch.name)) {
|
|
116
|
-
ours.add(meta.tokenId);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
if (revokeSuperseded) {
|
|
120
|
-
for (const tokenId of ours) {
|
|
121
|
-
await api.revokeCredential(options.projectId, branch.id, tokenId);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
vars,
|
|
126
|
-
credential: {
|
|
127
|
-
issued: true,
|
|
128
|
-
keys: secretKeys,
|
|
129
|
-
revoked: revokeSuperseded ? [...ours] : [],
|
|
130
|
-
superseded: revokeSuperseded ? [] : [...ours],
|
|
131
|
-
},
|
|
132
|
-
};
|
|
5
|
+
* Resolve a branch's env while keeping one-time secrets the caller already holds.
|
|
6
|
+
*
|
|
7
|
+
* {@link fetchEnvKeys} — and the public `fetchEnv` — only ever *fetch*. The Neon API returns a
|
|
8
|
+
* credential's `api_token` / `s3_secret_access_key` exactly once, at mint time, so "fetching"
|
|
9
|
+
* them means minting a new credential; a plain `fetchEnv` on every `neon dev` start or `env
|
|
10
|
+
* pull` would leave a live credential behind each time. This is the wrapper that avoids that:
|
|
11
|
+
* it looks at what the caller already has, decides what is still usable, and asks `fetchEnv`
|
|
12
|
+
* for only the rest.
|
|
13
|
+
*
|
|
14
|
+
* The check is a real verification, not a presence test. A persisted secret is kept only when
|
|
15
|
+
* it names a credential that still exists on this branch, is not revoked or expired, and
|
|
16
|
+
* carries every scope the policy needs. A `.env.example` placeholder, a credential revoked in
|
|
17
|
+
* the console, one copied in from another branch, or one predating a newly-enabled feature all
|
|
18
|
+
* fail that check and get replaced.
|
|
19
|
+
*
|
|
20
|
+
* None of this needs local bookkeeping, because the secrets carry their own credential id:
|
|
21
|
+
* `AWS_ACCESS_KEY_ID` **is** the credential's `tokenId` (the storage gateway authenticates
|
|
22
|
+
* against the full id), and the AI Gateway token is minted as `nt_live_<tokenIdShort>_<secret>`,
|
|
23
|
+
* where `tokenIdShort` is what the credentials list reports. The env source being replaced is
|
|
24
|
+
* the record of what the last call issued.
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { fetchEnvReusingSecrets } from "../_shared/env-core/reuse-secrets.js";
|
|
28
|
+
*
|
|
29
|
+
* const { vars, credential } = await fetchEnvReusingSecrets(config, {
|
|
30
|
+
* projectId,
|
|
31
|
+
* branch: "main",
|
|
32
|
+
* env: { ...process.env, ...readEnvFile(".env") },
|
|
33
|
+
* });
|
|
34
|
+
* if (credential.issued) console.log(`new values for ${credential.keys.join(", ")}`);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
async function fetchEnvReusingSecrets(config, options) {
|
|
38
|
+
const { env: source = process.env, revokeSuperseded = true, ...fetchOptions } = options;
|
|
39
|
+
const api = options.api ?? createApiFromOptions(options);
|
|
40
|
+
const { branch, desired } = await resolveBranchPolicy(config, options, api);
|
|
41
|
+
const storageEnabled = (desired.preview?.buckets.length ?? 0) > 0;
|
|
42
|
+
const gatewayEnabled = desired.preview?.aiGatewayEnabled ?? false;
|
|
43
|
+
const secretKeys = credentialEnvKeys({
|
|
44
|
+
storage: storageEnabled,
|
|
45
|
+
aiGateway: gatewayEnabled
|
|
46
|
+
});
|
|
47
|
+
if (secretKeys.length === 0) {
|
|
48
|
+
const fetched = await fetchEnvKeys(config, fetchOptions, null);
|
|
49
|
+
return {
|
|
50
|
+
vars: preferPersisted(toEntries(fetched), source),
|
|
51
|
+
credential: {
|
|
52
|
+
issued: false,
|
|
53
|
+
keys: [],
|
|
54
|
+
revoked: [],
|
|
55
|
+
superseded: []
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const persisted = readPersistedSecrets(source);
|
|
60
|
+
const complete = (!storageEnabled || Boolean(persisted.accessKeyId && persisted.secretAccessKey)) && (!gatewayEnabled || Boolean(persisted.apiToken));
|
|
61
|
+
const named = persisted.accessKeyId !== "" || persisted.apiToken !== "" ? namedCredentials(await api.listCredentials(options.projectId, branch.id), persisted) : {
|
|
62
|
+
storage: null,
|
|
63
|
+
gateway: null
|
|
64
|
+
};
|
|
65
|
+
const reusable = complete ? reusableCredential(named, {
|
|
66
|
+
storageEnabled,
|
|
67
|
+
gatewayEnabled
|
|
68
|
+
}) : null;
|
|
69
|
+
const scopes = previewCredentialScopes(desired.preview);
|
|
70
|
+
const keep = reusable !== null && credentialScopesSatisfied(reusable.scopes, scopes);
|
|
71
|
+
const allKeys = policyEnvKeys(desired);
|
|
72
|
+
const fetchKeys = keep ? allKeys.filter((key) => !secretKeys.includes(key)) : allKeys;
|
|
73
|
+
const fetched = await fetchEnvKeys(config, {
|
|
74
|
+
...fetchOptions,
|
|
75
|
+
branchId: branch.id,
|
|
76
|
+
api
|
|
77
|
+
}, fetchKeys);
|
|
78
|
+
const vars = preferPersisted(toEntries(fetched), source);
|
|
79
|
+
if (keep) {
|
|
80
|
+
for (const key of secretKeys) {
|
|
81
|
+
const value = source[key];
|
|
82
|
+
if (value !== void 0) vars[key] = value;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
vars,
|
|
86
|
+
credential: {
|
|
87
|
+
issued: false,
|
|
88
|
+
keys: secretKeys,
|
|
89
|
+
revoked: [],
|
|
90
|
+
superseded: []
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const ours = /* @__PURE__ */ new Set();
|
|
95
|
+
for (const meta of [named.storage, named.gateway]) if (meta !== null && meta.principalType === "user" && meta.name === credentialName(branch.name)) ours.add(meta.tokenId);
|
|
96
|
+
if (revokeSuperseded) for (const tokenId of ours) await api.revokeCredential(options.projectId, branch.id, tokenId);
|
|
97
|
+
return {
|
|
98
|
+
vars,
|
|
99
|
+
credential: {
|
|
100
|
+
issued: true,
|
|
101
|
+
keys: secretKeys,
|
|
102
|
+
revoked: revokeSuperseded ? [...ours] : [],
|
|
103
|
+
superseded: revokeSuperseded ? [] : [...ours]
|
|
104
|
+
}
|
|
105
|
+
};
|
|
133
106
|
}
|
|
134
107
|
/** Read the branch credential's secrets out of an env source. */
|
|
135
108
|
function readPersistedSecrets(source) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
109
|
+
const storage = NEON_ENV_VAR_KEYS.storage;
|
|
110
|
+
const gateway = NEON_ENV_VAR_KEYS.aiGateway;
|
|
111
|
+
return {
|
|
112
|
+
accessKeyId: source[storage.accessKeyId] ?? "",
|
|
113
|
+
secretAccessKey: source[storage.secretAccessKey] ?? "",
|
|
114
|
+
apiToken: source[gateway.apiKey] ?? ""
|
|
115
|
+
};
|
|
143
116
|
}
|
|
144
117
|
/**
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
118
|
+
* Keep a persisted value rather than overwriting it with an empty fetched one.
|
|
119
|
+
*
|
|
120
|
+
* Neon Auth's `base_url` is the case that needs this: integrations created before the API
|
|
121
|
+
* returned it answer with an empty string, and the persisted copy is the only one left. An
|
|
122
|
+
* empty fetched value never carries more information than a non-empty persisted one, so
|
|
123
|
+
* preferring the latter is safe for every var — and it keeps a pull from blanking a working
|
|
124
|
+
* line in someone's `.env`.
|
|
125
|
+
*/
|
|
153
126
|
function preferPersisted(vars, source) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
return out;
|
|
127
|
+
const out = { ...vars };
|
|
128
|
+
for (const [key, value] of Object.entries(out)) {
|
|
129
|
+
if (value !== "") continue;
|
|
130
|
+
const persisted = source[key];
|
|
131
|
+
if (persisted !== void 0 && persisted !== "") out[key] = persisted;
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
163
134
|
}
|
|
164
135
|
/**
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
136
|
+
* The credential id embedded in an AI Gateway token. The API mints them as
|
|
137
|
+
* `nt_live_<tokenIdShort>_<secret>`, and `tokenIdShort` is the public identifier the credentials
|
|
138
|
+
* list reports — so a persisted token names the credential that issued it. Returns `null` for
|
|
139
|
+
* anything not in that shape (a `.env.example` placeholder, a hand-typed value), which callers
|
|
140
|
+
* treat as unverifiable.
|
|
141
|
+
*/
|
|
171
142
|
function gatewayTokenIdShort(apiToken) {
|
|
172
|
-
|
|
143
|
+
return /^nt_live_([^_]+)_.+$/.exec(apiToken)?.[1] ?? null;
|
|
173
144
|
}
|
|
174
145
|
/** Whether an issued credential can still be used: not revoked, not past its expiry. */
|
|
175
146
|
function isLiveCredential(meta, now) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const expiresAt = Date.parse(meta.expiresAt);
|
|
181
|
-
return Number.isNaN(expiresAt) || expiresAt > now;
|
|
147
|
+
if (meta.revokedAt !== void 0) return false;
|
|
148
|
+
if (meta.expiresAt === void 0) return true;
|
|
149
|
+
const expiresAt = Date.parse(meta.expiresAt);
|
|
150
|
+
return Number.isNaN(expiresAt) || expiresAt > now;
|
|
182
151
|
}
|
|
183
152
|
/**
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
153
|
+
* The live credentials the persisted secrets name — at most one per half. A half that names
|
|
154
|
+
* nothing contributes nothing, which is what a placeholder, a credential revoked in the
|
|
155
|
+
* console, and one copied in from another branch all look like from here.
|
|
156
|
+
*/
|
|
188
157
|
function namedCredentials(live, persisted) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
? (usable.find((meta) => meta.tokenId === persisted.accessKeyId) ??
|
|
196
|
-
null)
|
|
197
|
-
: null,
|
|
198
|
-
gateway: shortId
|
|
199
|
-
? (usable.find((meta) => meta.tokenIdShort === shortId) ?? null)
|
|
200
|
-
: null,
|
|
201
|
-
};
|
|
158
|
+
const usable = live.filter((meta) => isLiveCredential(meta, Date.now()));
|
|
159
|
+
const shortId = persisted.apiToken ? gatewayTokenIdShort(persisted.apiToken) : null;
|
|
160
|
+
return {
|
|
161
|
+
storage: persisted.accessKeyId ? usable.find((meta) => meta.tokenId === persisted.accessKeyId) ?? null : null,
|
|
162
|
+
gateway: shortId ? usable.find((meta) => meta.tokenIdShort === shortId) ?? null : null
|
|
163
|
+
};
|
|
202
164
|
}
|
|
203
165
|
/**
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
166
|
+
* The credential the persisted secrets can be *reused* as, or `null`.
|
|
167
|
+
*
|
|
168
|
+
* Strict on purpose: every half the policy enables has to name a live credential, and when both
|
|
169
|
+
* features are enabled they must name the *same* one — they share a single credential, so
|
|
170
|
+
* halves that disagree came from two different calls and neither can be trusted.
|
|
171
|
+
*/
|
|
210
172
|
function reusableCredential(named, enabled) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
? named.storage
|
|
216
|
-
: null;
|
|
217
|
-
}
|
|
218
|
-
if (enabled.storageEnabled)
|
|
219
|
-
return named.storage;
|
|
220
|
-
if (enabled.gatewayEnabled)
|
|
221
|
-
return named.gateway;
|
|
222
|
-
return null;
|
|
173
|
+
if (enabled.storageEnabled && enabled.gatewayEnabled) return named.storage && named.gateway && named.storage.tokenId === named.gateway.tokenId ? named.storage : null;
|
|
174
|
+
if (enabled.storageEnabled) return named.storage;
|
|
175
|
+
if (enabled.gatewayEnabled) return named.gateway;
|
|
176
|
+
return null;
|
|
223
177
|
}
|
|
178
|
+
//#endregion
|
|
179
|
+
export { fetchEnvReusingSecrets };
|